LeetCode 力扣 热题 100道(二十)三数之和(C++)
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
如下代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end()); // 排序数组
for (int i = 0; i < nums.size(); ++i) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // 跳过重复的固定元素
int left = i + 1, right = nums.size() - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
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;
} else if (sum < 0) {
++left; // 和小于零,左指针右移增大和
} else {
--right; // 和大于零,右指针左移减小和
}
}
}
return result;
}
};
排序数组:
通过 sort(nums.begin(), nums.end())
,便于使用双指针方法。
跳过重复元素:
在外层循环中,如果当前 nums[i]
等于前一个值,则跳过。
在双指针部分,跳过连续相同的值以避免重复结果。
双指针查找:
左右指针收缩查找满足条件的组合。
根据当前和的值决定移动左指针还是右指针。