3Sum
问题描述:任意给一个数组,在数组中找到三元组(a,b,c)使得a+b+c=0。如果某符合要求的三元组有重复多个,也只取一个,要求找到所有的三元组。
一开始自己想了一个暴力搜索的方法,结果超时了,然后想一层一层剪枝,还是不行。最后看了一下别人的思路,用了双指针解决了问题。
在我原来的思路里,我是将数组进行排序,然后固定两个数字,然后找到符合要求的第三个数字。现在就只固定住一个数字,然后用两个指针分别指向该数字之后的数组的头尾两个数,若他们的和等于固定数字的相反数,那么与固定数字凑成要找的三元组,紧接着头指针加一,尾指针减一,注意要跳过重复的数字,再进行判断。如果他们的和大于固定数字的相反数,则尾指针减一再进行判断,如果他们的和小于固定数字的相反数,则头指针加一再进行判断,直到头尾指针相遇。注意,在固定第一个数字时,如果该数字和前一个数字相同,可以跳过,因为前一个操作已经固定过相同的数字了。
vector<vector<int>> threeSum(vector<int>& nums)
{
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for (int k = 0; k < nums.size(); ++k)
{
if (nums[k] > 0) break;
if (k > 0 && nums[k] == nums[k - 1]) continue;
int i = k + 1, j = nums.size() - 1;
while(i<j)
{
if (nums[i] + nums[j] == target)
{
res.push_back({nums[k], nums[i], nums[j]});
while (i < j && nums[i] == nums[i + 1]) ++i;
while (i < j && nums[j] == nums[j - 1]) --j;
++i; --j;
}
else if (nums[i] + nums[j] < target) ++i;
else --j;
}
}
return res;
}