Keshawn_lu's Blog

Leetcode 15. 三数之和

字数统计: 603阅读时长: 2 min
2020/06/12 Share

题目简介:

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

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

示例:

1
2
3
4
5
6
7
给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

思路:

首先将数组进行从小到大的排序,然后遍历数组,将每次遍历到的数字作为固定数字,并设置双指针,left = i + 1right = nums.size() - 1。(即指针的范围在当前遍历数字之后)

nums[i] + nums[left] + nums[right] == 0,则加入结果数组中,并使左右指针指向距离最近的、不和本身数字相等的数字(防止重复)。

我们可以这样想,若两个指针都指向和之前相等的数字,那三个数字就是没有变化的,必然重复。若一个指针指向和之前相等的数字,那么新的三个数字相加必不可能等于0

sum < 0,则说明left指向的数字太小了,往右移动;反之right指向的数字太大了,往左移动。

tips:

  • 若遍历到的数字nums[i] > 0,那么在nums[i]之后的数字必然都> 0,相加的结果必然不等于0,所以就无需再遍历了,直接break即可。
  • nums[i] == nums[i - 1],那么固定数字与之前的相等,结果肯定也和之前是一样的,continue即可。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {

vector<vector<int>> res;

sort(nums.begin(), nums.end());

int left, right;

for(int i = 0; i < nums.size(); i++){

//最小值都>0,相加不可能等于0,也不用管后续的数字了,必然>0。
if(nums[i] > 0)
break;

//去重,固定数相等,结果也相等
if(i > 0 && nums[i] == nums[i - 1])
continue;

left = i + 1;
right = nums.size() - 1;

while(left < right){

int sum = nums[i] + nums[left] + nums[right];

if(sum == 0){

vector<int> temp = {nums[i], nums[left], nums[right]};
res.push_back(temp);

//去重
while(left < right && nums[left] == nums[left + 1])
left++;
while(left < right && nums[right] == nums[right - 1])
right--;

left++;
right--;
}
else if(sum < 0)
left++; //sum值过小,left向右移动
else
right--;
}
}

return res;

}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: