18. 四数之和(双指针法)(Leetcode刷题笔记)
https://lunan0320.cn
文章目录
题目
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
解题代码 C++(核心代码)
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
//对nums数组从小到大排序
sort(nums.begin(), nums.end());
for (int k = 0; k < nums.size(); k++) {
//判断k 去重
if (k > 0 && nums[k] == nums[k - 1]) continue;
for (int i = k + 1; i < nums.size(); i++) {
//判断i去重
if (i > k + 1 && nums[i] == nums[i - 1]) continue;
int new_target = target - nums[i] - nums[k];
int left = i + 1, right = nums.size() - 1;
//left到right的区间收敛
while (right > left) {
if (nums[left] + nums[right] > new_target) right--;
else if (nums[left] + nums[right] < new_target) left++;
else {
res.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});
//right侧去重
while (right > left && nums[right] == nums[right - 1]) right--;
//left侧去重
while (right > left && nums[left] == nums[left + 1]) left++;
//更新left和right
right--;
left++;
}
}
}
}
return res;
}
};
解题代码 C++(本地编译运行)
// head.h
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;
// myHashMap.h
#include "head.h"
//18题 双指针法
class FourSum {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
//对nums数组从小到大排序
sort(nums.begin(), nums.end());
for (int k = 0; k < nums.size(); k++) {
//判断k 去重
if (k > 0 && nums[k] == nums[k - 1]) continue;
for (int i = k + 1; i < nums.size(); i++) {
//判断i去重
if (i > k + 1 && nums[i] == nums[i - 1]) continue;
int new_target = target - nums[i] - nums[k];
int left = i + 1, right = nums.size() - 1;
//left到right的区间收敛
while (right > left) {
if (nums[left] + nums[right] > new_target) right--;
else if (nums[left] + nums[right] < new_target) left++;
else {
res.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});
//right侧去重
while (right > left && nums[right] == nums[right - 1]) right--;
//left侧去重
while (right > left && nums[left] == nums[left + 1]) left++;
//更新left和right
right--;
left++;
}
}
}
}
return res;
}
};
// main.cpp
#include "myHashMap.h"
//18题 双指针法
int main() {
FourSum solution;
vector<int> nums = {-2,-1,-1,1,1,2,2};
int target = 0;
vector<vector<int>> res = solution.fourSum(nums, target);
for (auto sub : res) {
for (auto i : sub) {
cout << i << " ";
}
cout << endl;
}
}