15.三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例: |
---|
给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ] |
精选题解中的解题思路:
- 特判,对于数组长度 nn,如果数组为 nullnull 或者数组长度小于 33,返回[]。
- 对数组进行排序。
- 遍历排序后数组:
- 若 nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
- 对于重复元素:跳过,避免出现重复解
- 令左指针 L=i+1,右指针 R=n-1,当 L<R 时,执行循环:
- 当 nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,R 移到下一位置,寻找新的解
- 若和大于 0,说明 nums[R]nums[R] 太大,RR 左移
- 若和小于 0,说明 nums[L]nums[L] 太小,LL 右移
我进行了c++版的复现:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
int L, R, t=0;
if(nums.size() < 3) return res;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++){
if(nums[i] > 0) break;
L = i+1; R = nums.size()-1;
while(L<R){
if(nums[i] + nums[L] + nums[R] == 0){
res.push_back(vector<int> (3,1));
res[t][0] = nums[i];
res[t][1] = nums[L];
res[t++][2] = nums[R];
while(L<R && nums[L]==nums[L+1]) L=L+1;
while(L<R && nums[R]==nums[R-1]) R=R-1;
R--;L++;
}
else if(nums[i] + nums[L] + nums[R] > 0) R--;
else if(nums[i] + nums[L] + nums[R] < 0) L++;
}
while(i < nums.size()-1 && nums[i]==nums[i+1]) i++;
}
return res;
}
};
在双指针的移动上特别容易出错,一定要仔细!我错了好几次。
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.