【优选算法】四数之和(双指针算法)
必须有为成功付出代价的决心,然后想办法付出这个代价。
目录
1.【题目链接】
2.【算法原理】
3.【代码】
1.【题目链接】
18. 四数之和 - 力扣(LeetCode)
2.【算法原理】
与前面三数之和原理很像
解法一:排序 + 暴力枚举 + 利用set去重(超时)
用四个for循环枚举出所有情况再去重。
解法二 :
- 排序
- 先固定一个数 a
- 剩下的范围进行 “三数之和” 算法,找到三个数使和等于 target - a(三数之和:先固定一个数 b,再利用双指针算法求剩下的数之和为 target - a - b)
注意:
- 去重:对 left、right、a、b 进行去重
- 不漏:在找到一种结果之后,left ++,right -- 继续寻找
3.【代码】
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ret;
int n = nums.size();
//1.排序
sort(nums.begin(), nums.end());
//2.先固定一个数a,在剩下的数里面利用三数之和等于target-a
for (int i = 0; i < n; )
{
//先固定一个数b,在剩下的数里面利用双指针算法
for (int j = i + 1; j < n; )
{
int left = j + 1, right = n - 1;
//避免数据溢出,我们用long long类型
long long count = (long long)target - nums[i] - nums[j];
while (left < right)
{
int sum = nums[left] + nums[right];
if (sum > count) right--;
else if (sum < count) left++;
else
{
ret.push_back({ nums[i],nums[j],nums[left++],nums[right--] });
//去重一,left和right
while (left < right && nums[left] == nums[left - 1]) left++;
while (left < right && nums[right] == nums[right + 1]) right--;
}
}
//去重二
j++;
while (j < n && nums[j] == nums[j - 1]) j++;
}
//去重三
i++;
while (i < n && nums[i] == nums[i - 1]) i++;
}
return ret;
}
};
完——
看完算法原理一定要先自己尝试写代码,不要直接看,这样做很锻炼自己的代码能力。
前面的三数之和题如果理解透彻且代码能够自己写出来,其实这道四数之和题自己也是能够写出来的,就是这道题有一个数据溢出的问题解决一下就好了。
双指针算法就此结束了,下一个算法思想开始。。。