题目(原题链接)
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
题目分析:
1,对于三个数,可以尝试与两个数近似的的解题思路(两数之和),首先先sort将数据有序化,先利用循环来框定一个数,再对剩下的俩数利用头尾指针相向遍历,然后记录符合的数据,重复的就跳过;
代码分析:
1,对于第一位变量i遍历的时候,可以考虑此变量若与前一此遍历所对应的数据相同,可以将此变量++,既跳过此次循环,因为题目说不包含重复的三元组;
2,对于后两个相向变量,可以将执行过程的条件设定为(头j<尾k)以便及时终止不必要的过程,产生错误答案;
3,若i与后两个连续的数据相加,结果都>0的话,便可以结束所有的循环了,因为数据是依次增大的,当i递增到此处,无论后面的j和k怎么变化,结果都是会>0的,既无法满足=0的条件;
4,若i与数组最末尾的两个数据相加都<0,便可以结束此次i的循环了,直接i++;因为i与数组里的最大的两个值都小于0,说明这个i变量无法成立答案,于是便跳过;
5,利用for (++j; j < k && nums[j] == nums[j - 1]; ++j);来判断并修改j和k两个相向指针,可以快速的达到跳过重复元素的效果;
最后献上灵神的代码,详细可点入链接查看;
class Solution {
public:
vector<vector<int>> threeSum(vector<int> &nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
int n = nums.size();
for (int i = 0; i < n - 2; ++i) {
int x = nums[i];
if (i && x == nums[i - 1]) continue; // 跳过重复数字
if (x + nums[i + 1] + nums[i + 2] > 0) break; // 优化一
if (x + nums[n - 2] + nums[n - 1] < 0) continue; // 优化二
int j = i + 1, k = n - 1;
while (j < k) {
int s = x + nums[j] + nums[k];
if (s > 0) --k;
else if (s < 0) ++j;
else {
ans.push_back({x, nums[j], nums[k]});
for (++j; j < k && nums[j] == nums[j - 1]; ++j); // 跳过重复数字
for (--k; k > j && nums[k] == nums[k + 1]; --k); // 跳过重复数字
}
}
}
return ans;
}
};
作者:灵茶山艾府
链接:https://leetcode.cn/problems/3sum/solutions/1968332/shuang-zhi-zhen-xiang-bu-ming-bai-yi-ge-pno55/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。