
思路分析
1. 排序预处理
sort(nums.begin(), nums.end());
- 目的:将数组升序排序,便于后续双指针操作和去重。
- 作用:
- 方便固定一个数后,用双指针快速寻找另外两个数。
- 相同数字相邻排列,便于跳过重复值。
2. 外层循环固定第一个数
for (int i = 0; i < n - 2; i++) {if (i > 0 && nums[i] == nums[i - 1]) {continue; }int target = -nums[i];
}
- 去重逻辑:
- 如果
nums[i]
与前一个数 nums[i-1]
相同,直接跳过,避免重复解。
- 目标转换:
- 将三数之和问题转化为两数之和问题:
nums[j] + nums[k] = target = -nums[i]
。
3. 内层双指针寻找两数之和
int j = i + 1, k = n - 1;
while (j < k) {if (nums[j] + nums[k] < target) {j++; } else if (nums[j] + nums[k] > target) {k--; } else {res.push_back({nums[i], nums[j], nums[k]});while (j < k && nums[j] == nums[j + 1]) j++;while (j < k && nums[k] == nums[k - 1]) k--;j++;k--;}
}
- 双指针移动规则:
- 和太小:左指针
j
右移(增大和)。 - 和太大:右指针
k
左移(减小和)。 - 匹配成功:记录解,并跳过所有重复的
nums[j]
和 nums[k]
。
- 去重逻辑:
- 在找到有效解后,跳过所有与当前
nums[j]
和 nums[k]
相同的值,避免重复解。
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n=nums.size(); vector<vector<int>> res;sort(nums.begin(),nums.end());for(int i=0;i<n-2;i++){ if(i>0&&nums[i-1]==nums[i]){continue;}int a=-nums[i];int j=i+1,k=n-1;while(j<k){if(nums[j]+nums[k]<a){j++;}else if(nums[j]+nums[k]>a){k--;}else{ res.push_back({nums[i],nums[j],nums[k]});while(j<k&&nums[j+1]==nums[j]){j++;}while(j<k&&nums[k-1]==nums[k]){k--;}j++;k--;}}}return res;}
};