LeetCode(15) - 3Sum

  这道题给你一个数组,找到所有三个数加起来等于0的数字并存到List里。暴力搜索的话大概要耗费O(n^3)的时间,但是如果这个数组是有序的话,搜索起来就会相对简单,排序大概要花费O(nlog(n))的时间,有序搜索只需要花费O(n^2)的时间,所以,思路是这样:

  1. 先排序。
  2. 外循环i纪录第一个数字,内循环采用2 pointer的方法,当sum>0,tail往左移,sum < 0,head往右移。
  3. 碰到sum = nums[i] + nums[head] + nums[tail]时,把三个数字存到list里,并把list存到最外面的list2里面。
  4. 注意数字重复的情况,我用了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 }
原文地址:https://www.cnblogs.com/kepuCS/p/5244062.html