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]
]

链接:https://leetcode.com/problems/3sum/#/description

4/9/2017

7%, 156ms

时间复杂度O(N^2), 空间复杂度O(N)

注意的问题:

1. 当没有合法结果时,只需要返回空list即可,不需要[[]]

2. 第11行是会覆盖掉之前相同元素的,但这也是想要的,因为在双重循环里会想要找大于j的下标,否则j下标的值会被重复计算。

3. 第16,19行是避免重复值。

 1 public class Solution {
 2     public List<List<Integer>> threeSum(int[] nums) {
 3         Map<Integer, Integer> hm = new HashMap<Integer, Integer>();
 4         List<List<Integer>> ret = new ArrayList<List<Integer>>();
 5         if (nums.length < 3) return ret;
 6         Arrays.sort(nums);
 7 
 8         if (nums[nums.length - 1] < 0 || nums[0] > 0) {
 9             return ret;
10         }
11         for (int i = 0; i < nums.length; i++) {
12             hm.put(nums[i], i);
13         }
14         
15         for (int i = 0; i < nums.length; i++) {
16             if (i != 0 && nums[i] == nums[i - 1]) continue;
17             for (int j = i + 1; j < nums.length; j++) {
18                 if (nums[i] > 0) break;
19                 if (nums[j] == nums[j - 1] && j != i + 1) continue;
20                 if (hm.containsKey(- nums[i] - nums[j]) && hm.get(- nums[i] - nums[j]) > j) {
21                     List<Integer> l = new ArrayList<Integer>();
22                     l.add(nums[i]);
23                     l.add(nums[j]);
24                     l.add(- nums[i] - nums[j]);
25                     ret.add(l);
26                 }
27             }
28         }
29         return ret;
30     }
31 }

可以不需要hashmap,空间复杂度降为1,做法是在i既定之后用2个指针从两侧找合适的值。

注意第8行也是为了去重

 1 public class Solution {
 2     public List<List<Integer>> threeSum(int[] nums) {
 3         List<List<Integer>> res = new ArrayList<>();
 4         if (nums == null) return res;
 5         Arrays.sort(nums);
 6         
 7         for (int i = 0; i < nums.length - 2; i++) {
 8             if (i > 0 && nums[i] == nums[i - 1]) continue;
 9             int lo = i + 1;
10             int hi = nums.length - 1;
11             while (lo < hi) {
12                 int sum = nums[i] + nums[lo] + nums[hi];
13                 if (sum == 0) {
14                     List<Integer> list = new ArrayList<>();
15                     list.add(nums[i]);
16                     list.add(nums[lo]);
17                     list.add(nums[hi]);
18                     res.add(list);
19                     lo++;
20                     hi--;
21                     while (lo < hi && nums[lo] == nums[lo - 1]) lo++;
22                     while (lo < hi && nums[hi] == nums[hi + 1]) hi--;
23                 } else if (sum < 0) {
24                     lo++;
25                 } else {
26                     hi--;
27                 }
28             }
29         }
30         return res;
31     }
32 }

更多讨论:https://discuss.leetcode.com/category/23/3sum

原文地址:https://www.cnblogs.com/panini/p/6687345.html