这道题给你一个数组,找到所有三个数加起来等于0的数字并存到List里。暴力搜索的话大概要耗费O(n^3)的时间,但是如果这个数组是有序的话,搜索起来就会相对简单,排序大概要花费O(nlog(n))的时间,有序搜索只需要花费O(n^2)的时间,所以,思路是这样:
- 先排序。
- 外循环i纪录第一个数字,内循环采用2 pointer的方法,当sum>0,tail往左移,sum < 0,head往右移。
- 碰到sum = nums[i] + nums[head] + nums[tail]时,把三个数字存到list里,并把list存到最外面的list2里面。
- 注意数字重复的情况,我用了hashset来解决。
代码如下:
1 public class Solution { 2 public List<List<Integer>> threeSum(int[] nums) { 3 List<List<Integer>> list = new ArrayList<List<Integer>>(); 4 Set<Integer> set = new HashSet<Integer>(); 5 //排序 6 Arrays.sort(nums); 7 for (int i = 0; i < nums.length - 2; i++) { 8 //判断有没有重复。 9 if (!set.add(nums[i])) continue; 10 //如果nums[i]大于0,就没有再判断的必要了 11 if (nums[i] > 0) break; 12 int head = i+1; 13 int tail = nums.length - 1; 14 int last = nums[head]; 15 while (head < tail) { 16 if (head != i+1 && nums[head] == last) { 17 head++; 18 continue; 19 } 20 int sum = nums[i] + nums[head] + nums[tail]; 21 if (sum > 0) tail--; 22 else if (sum < 0) { 23 last = nums[head]; 24 head++; 25 } 26 else { 27 List<Integer> arrayList = new ArrayList<Integer>(); 28 arrayList.add(nums[i]); 29 arrayList.add(nums[head]); 30 arrayList.add(nums[tail]); 31 list.add(arrayList); 32 last = nums[head]; 33 head++; 34 tail--; 35 } 36 } 37 } 38 return list; 39 } 40 }