LeetCode-3Sum

来源:互联网 发布:apache 配置文件路径 编辑:程序博客网 时间:2024/06/05 12:05

算法分析与设计第6周博客

15. 3Sum

Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],A solution set is:[  [-1, 0, 1],  [-1, -1, 2]]
题目的意思很简单,就是给出一组整数,找出其中所有三个和为零的数的集合。

如果使用暴力枚举法的话,那么就是从n个数中取出3个,计算它们的和,看其是否为零,这样的时间复杂度是O(n^3),算是很低的效率了。

如果先进行排序呢,排序的时间复杂度是O(n*log(n)),这样就得到了一个有序的数组,如果我们首先确定一个数A[i],然后去剩下的A[i+1]-A[n-1]中寻找两个数,这两个数的和是-A[i]。这样,就把这个问题由三个数的和变成了两个数的和。如果读者熟悉的话,在一个有序的数组里,寻找两个数的和是否等于某个数,这个算法的时间复杂度是O(n),具体的代码如下:

boolean twoSum(int[] nums, int target) {for (int i = 0, j = nums.length-1; i < j; ) {if (nums[i]+nums[j] > target)--j;else if (nums[i]+nums[j] < target)++i;elsereturn true;}return false;}
这样,就基本解决这个问题了。还有一个需要注意的细节是,返回的集合中是不能有相同的元素的,所以遇到相同的元素的时候,需要跳过。整体的代码如下:

import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.List;import java.util.Set;public class Solution {public List<List<Integer>> threeSum(int[] nums) {        List<List<Integer>> res = new ArrayList<>();        Arrays.sort(nums);        int i = 0, j = nums.length-1;        for (i = 0; i < nums.length; ++i) {            if (i > 0 && nums[i] == nums[i-1])                continue;int s = i+1, e = nums.length-1;while (s < e) {if (nums[s]+nums[e]+nums[i] > 0) {--e;} else if (nums[s]+nums[e]+nums[i] < 0) {++s;} else {List<Integer> one = new ArrayList<>();        one.add(nums[i]);        one.add(nums[s]);        one.add(nums[e]);        res.add(one);                                        do {                        ++s;                    } while (s < nums.length && nums[s] == nums[s-1]);                    do {                        --e;                    } while (e > 0 && nums[e] == nums[e+1]);}}}        return res;    }}

这个算法的时间复杂度右两部分组成,排序(O(n*log(n)),需找三个数的和O(n*n),所以最终的时间复杂度也是O(n^2)。

原创粉丝点击