题目如下:
解题思路:
- 类似求三数之和,将数组排序后,使用双循环固定两个数,用双指针找另外两个数,通过比较与target的大小,移动指针。
- 注意重复元素。
代码如下:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
vector<int> temp;
//先将数组排序(升序)
sort(nums.begin(), nums.end());
//类似三数之和
//使用双循环固定两个数,用双指针找另外两个数,通过比较与target的大小,移动指针
//固定头部
for(int base_begin = 0; base_begin < nums.size(); base_begin++)
{
//跳过头部相同元素
if(base_begin > 0 && nums.at(base_begin) == nums.at(base_begin-1))
continue;
//固定尾部
for(int base_end = nums.size()-1; base_end > base_begin+2; base_end--)
{
//跳过尾部相同元素
if(base_end < nums.size()-1 && nums.at(base_end) == nums.at(base_end+1))
continue;
//头尾两个指针进行扫描,因为数组已排序,可以从base后面扫描,避免重复组合
int left = base_begin + 1;
int right = base_end - 1;
while(left < right)
{
int tt = nums.at(base_begin) + nums.at(base_end) + nums.at(left) + nums.at(right);
//若base_begin+base_end+left+right > target,则应减小,right左移
if(tt > target)
right--;
//若base_begin+base_end+left+right < target,则应增加,left右移
else if(tt < target)
left++;
//相等情况下得到一组解
else{
temp.clear();
temp.push_back(nums.at(base_begin));
temp.push_back(nums.at(left));
temp.push_back(nums.at(right));
temp.push_back(nums.at(base_end));
res.push_back(temp);
//如果 left 和 left+1 相同,则略过,避免出现重复组合
while (left < right && nums.at(left) == nums.at(left + 1))
++left;
//如果 right 和 right-1 相同,则略过,避免出现重复组合
while (left < right && nums.at(right) == nums.at(right - 1))
--right;
//处理下一对数
++left;
--right;
}
}
}
}
return res;
}
};