四数之和的解决方法--双指针+去重+剪枝
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四数之和的解决方法--双指针+去重+剪枝相关的知识,希望对你有一定的参考价值。
题目
题目解析
读完题目,发现需要去重!那么这就需要在排序的基础上,判断每次的选择和上一次是否相同,若相同则continue,由于是选择同一个数组元素的组合,所以无法使用哈希表进行优化,只能通过双指针,把两层循环优化为一层循环。
- 优化的关键:剪枝
- 最小的四个加起来若还是大于
target
则不可能存在等于target
的组合 =>break;
- 当前选择的数加上最大的三个数小于
target
则当前选择的数无法形成等于target
的四元组。=>continue;
代码以及效率
效率如下:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>>res;
int sz = nums.size();
if(sz<4)return res;
sort(nums.begin(),nums.end());
for(int i=0;i<sz-3;i++){
//对特殊情况剪枝:1.最小的四个加起来若还是大于target则不可能存在等于target的组合 2. 当前选择的数加上最大的三个数小于target则当前选择的数无法形成等于target的四元组。
if((nums[i]+nums[i+1]+nums[i+2]+nums[i+3])>target)
break;
if(nums[i]+nums[sz-3]+nums[sz-2]+nums[sz-1]<target)
continue;
//去重处理,此次选择的数不能和上次相同
if(i>0&&nums[i]==nums[i-1])
continue;
for(int j=i+1;j<sz-2;j++){
//对特殊情况剪枝:1.最小的四个加起来若还是大于target则不可能存在等于target的组合 2. 当前选择的数加上最大的三个数小于target则当前选择的数无法形成等于target的四元组。
if(nums[i]+nums[j]+nums[j+1]+nums[j+2]>target)
break;
if(nums[i]+nums[j]+nums[sz-2]+nums[sz-1]<target)
continue;
//去重处理,此次选择的数不能和上次相同
if(j>i+1&&nums[j]==nums[j-1])
continue;
int t = target-(nums[i]+nums[j]);
int l = j+1,r = sz-1;
//双指针优化最后两层循环。
while(l<r){
int&& q = nums[l]+nums[r];
if(q>t)r--;
else if(q<t)l++;
else{
res.emplace_back(vector<int>{nums[i],nums[j],nums[l],nums[r]});
r--;l++;
while(l<r&&nums[r]==nums[r+1])r--;
while(l<r&&nums[l]==nums[l-1])l++;
}
}
}
}
return res;
}
};
以上是关于四数之和的解决方法--双指针+去重+剪枝的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 581. 最短无序连续子数组/611. 有效三角形的个数/15. 三数之和/18. 四数之和(双指针)