[LeetCode] 15. 3Sum

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != ji != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

Example 1:

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]

Example 2:

Input: nums = []
Output: []

Example 3:

Input: nums = [0]
Output: []

Constraints:

  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

三数之和。

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题意是给一个数组,请问是否能找到这样的组合使得 a + b + c = 0?输出所有这样的 [a, b, c] 组合。

还是 two sum 的思路,双指针从两边往中间逼近。因为和是 0,所以可以先固定a的位置,然后找是否有 b + c = 0 - a 的组合。首先需要对数组排序,然后在执行过程中需要排除一些重复数字,避免最后的 output 有重复。同时,在遍历a的范围的时候,如果 a > 0 就可以直接跳过了,因为数组是排序过的,如果 a 大于 0,b,c 也必定大于0。

时间O(n^2)

空间O(n^2) - list of list

JavaScript实现

 1 /**
 2  * @param {number[]} nums
 3  * @return {number[][]}
 4  */
 5 var threeSum = function(nums) {
 6     const res = [];
 7     let left, right, sum;
 8     nums.sort((a, b) => a - b);
 9     for (let i = 0; i < nums.length - 2; i++) {
10         if (nums[i] > 0) break;
11         if (nums[i] === nums[i - 1]) continue;
12         left = i + 1;
13         right = nums.length - 1;
14         sum = 0 - nums[i];
15         while (left < right) {
16             if (nums[left] + nums[right] === sum) {
17                 res.push([nums[i], nums[left], nums[right]]);
18                 while (left < right && nums[left] === nums[left + 1]) {
19                     left++;
20                 }
21                 while (left < right && nums[right] === nums[right - 1]) {
22                     right--;
23                 }
24                 left++;
25                 right--;
26             } else if (nums[left] + nums[right] < sum) {
27                 left++;
28             } else {
29                 right--;
30             }
31         }
32     }
33     return res;
34 };

 

Java实现

 1 class Solution {
 2     public List<List<Integer>> threeSum(int[] nums) {
 3         List<List<Integer>> res = new ArrayList<>();
 4         // corner case
 5         if (nums == null || nums.length == 0) {
 6             return res;
 7         }
 8 
 9         // normal case
10         Arrays.sort(nums);
11         for (int i = 0; i < nums.length - 2; i++) {
12             // 对于一个排过序的数组,如果nums[i] > 0了,说明已经在数组的右半部分了
13             if (nums[i] > 0) {
14                 break;
15             }
16             // 跳过重复数字
17             if (i > 0 && nums[i] == nums[i - 1]) {
18                 continue;
19             }
20             int low = i + 1;
21             int hi = nums.length - 1;
22             int sum = 0 - nums[i];
23             while (low < hi) {
24                 if (nums[low] + nums[hi] == sum) {
25                     res.add(Arrays.asList(nums[i], nums[low], nums[hi]));
26                     while (low < hi && nums[low] == nums[low + 1]) {
27                         low++;
28                     }
29                     while (low < hi && nums[hi] == nums[hi - 1]) {
30                         hi--;
31                     }
32                     low++;
33                     hi--;
34                 } else if (nums[low] + nums[hi] < sum) {
35                     low++;
36                 } else {
37                     hi--;
38                 }
39             }
40         }
41         return res;
42     }
43 }

 

python3实现

 1 class Solution:
 2     def threeSum(self, nums: List[int]) -> List[List[int]]:
 3         res = []
 4         n = len(nums)
 5         if (not nums or n < 3):
 6             return res
 7     
 8         nums.sort()
 9         for i in range(n):
10             if (nums[i] > 0):
11                 return res
12             if (i > 0 and nums[i] == nums[i - 1]):
13                 continue
14             lo = i + 1
15             hi = n - 1
16             while (lo < hi):
17                 if (nums[i] + nums[lo] + nums[hi] == 0):
18                     res.append([nums[i], nums[lo], nums[hi]])
19                     while (lo < hi and nums[lo] == nums[lo + 1]):
20                         lo = lo + 1
21                     while (lo < hi and nums[hi] == nums[hi - 1]):
22                         hi = hi - 1
23                     lo = lo + 1
24                     hi = hi - 1
25                 elif(nums[i] + nums[lo] + nums[hi] > 0):
26                     hi = hi - 1
27                 else:
28                     lo = lo + 1
29         return res

 

two sum题目总结

LeetCode 题目总结

posted @ 2019-11-11 13:23  CNoodle  阅读(459)  评论(0编辑  收藏  举报