思路分析
- 三数之和,可以转化为两数之和的问题,依次遍历原数组,比如当前遍历到index为5的元素,只要另外两个值相加为0减nums[5]即可。而这两个值对应的下标假设分别为left和right,right即为nums.size()-1,left不需要从0开始,因为在遍历5之前,先遍历的0-4,因此如果在0-4有符合条件的,在遍历0-4时,5已经作为一个结果放进结果数组里了,因为不需要有重复的结果,所以left从index+1开始。
- 另外,如果相邻的2个值是一样的,则忽略,因为如果相等,意味着如果结果包含这两个值,则结果只需要保留先遍历到的即可,比如原数组为[-1, -1, 0, 1, 2],结果为[-1, -1, 2],很明显遍历index 0时,因为结果包含连续的两个-1,则遍历index 1时,只需要判断与前一个相等,即可继续前进,忽略当前值。
代码实现
class Solution
{
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
sort(nums.begin(), nums.end());
vector<vector<int>> res;
for (int i = 0; i < nums.size(); i++) {
if (i != 0 && nums[i] == nums[i - 1])
continue;
int dst = -1 * nums[i];
int left = i + 1, right = nums.size() - 1;
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == dst) {
res.push_back(vector<int>{nums[i], nums[left], nums[right]});
left++;
while (left < right && nums[left] == nums[left - 1]) {
left++;
}
right--;
while (left < right && nums[right] == nums[right + 1]) {
right--;
}
} else if (sum > dst) {
right--;
} else {
left++;
}
}
}
return res;
}
};