15. 三数之和
题目描述
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
思路
- 先排序,利用变量i遍历数组,找到nums[i]对应的nums[j],nums[k].
- 为了方便记忆,用left代替j,right代替k.对于每一个i,都尝试找到left和right,使得nums[i] + nums[left] + nums[right] = 0.
- 起初,left从i + 1往后找,right从n - 1往前找,当nums[i] + nums[left] + nums[right] > 0时,说明right太大了,需要right--,< 0时,说明left太小了,需要left++,=0时,说明找到了left和right,那么此时left++和right--,但是如果left++后,nums[left]的值没有改变,left需要继续++,right--后,nums[right]的值没有改变,right需要继续--,这样,三元组才不会重复。(因为已经排过序了,所以对于每一个i,其对应的let和right如果有重复的,必然是相邻的)
- 如果i + 1后,nums[i]的值没有改变,那么直接略过,因为上一次已经找到了合适的left和right.
代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int n = nums.size();
vector<vector<int>> result;
for(int i = 0;i < n;i++){
int left = i + 1;
int right = n - 1;
if(i > 0 && nums[i] == nums[i - 1]) continue;
while(left < right){
int value = nums[left] + nums[right];
if(nums[i] + value > 0) right--;
else if(nums[i] + value < 0) left++;
else{
result.push_back({nums[i],nums[left],nums[right]});
while(left < right && nums[left] == nums[left + 1]) left++;
while(left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
return result;
}
};

浙公网安备 33010602011771号