/*
* Leetcode18. 4Sum
* Funtion: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?
Find all unique quadruplets in the array which gives the sum of target.
* Example:
Input: given array S = [1, 0, -1, 0, -2, 2], and target = 0.
Output: [
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
Input1:[-3,-2,-1,0,0,1,2,3] 0
Expected1:[[-3,-2,2,3],[-3,-1,1,3],[-3,0,0,3],[-3,0,1,2],[-2,-1,0,3],[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Input2:[-1,2,2,-5,0,-1,4] 3
Expected2:[[-5,2,2,4],[-1,0,2,2]]
* Author: LKJ
* Date:2016/7/29
* Hint:related to 15.3Sum
(穷举第一个和第二个元素,对第三个和第四个元素使用首尾逼近来枚举)
具体思路和求3Sum的O(n2)方法相同,只是去重方法不同
符合条件的元组已经找出了,下次哈希到相同的结果认为它们原来的元组相同(假设哈希未出现冲突),则跳过保存该结果。
为了在求得符合条件的四元组后查找其哈希值时,提高查找速度,使用set或map来存储哈希值,其中的哈希值有序排列
调用这两种容器自身的查找函数可以提高查找效率(内部一般使用二分查找法)。
这里使用map和set在提交结果的时间上有所差别,应该二者内部实现还是有些差别,虽然可以将set也看做一种特殊map。
*/
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
class Solution {
private:
int myabs(int num){
if(num < 0) num = -num;
return num;
}
public:
vector< vector<int> > fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int len = nums.size();
int leftnum;
int rightnum;
int sum;
vector<int> preAns;
vector< vector<int> > ans;
for(int i = 0; i < len-3; i++){
if((i > 0) && (nums[i] == nums[i-1])) continue;//去重
for(int j = i+1; j < len-2; j++){
if((j > i+1) && (nums[j] == nums[j-1])) continue;//去重
leftnum = j+1;
rightnum = len-1;
while(leftnum < rightnum){
if((leftnum > j+1) && (nums[leftnum] == nums[leftnum-1])) {leftnum++; continue;} //去重
sum = nums[i] + nums[j] + nums[leftnum] + nums[rightnum];
if(sum == target){
preAns.push_back(nums[i]);
preAns.push_back(nums[j]);
preAns.push_back(nums[leftnum]);
preAns.push_back(nums[rightnum]);
ans.push_back(preAns);
preAns.clear();
}
if(sum > target){
rightnum--;
if(nums[rightnum] == nums[rightnum+1]) rightnum--;//去重
}else{
leftnum++;
if(nums[leftnum] == nums[leftnum-1]) leftnum++;//去重
}
}
}
}
//也可以使用set去重
/*
set< vector<int> > ans;
vector< vector<int> > newans;
set<vector<int>>::iterator it = ans.begin();
for(; it != ans.end(); it++)
newans.push_back(*it);
return newans;
*/
return ans;
}
};
int main(){
int myarr[7] = {-1,2,2,-5,0,-1,4};
vector<int> myin1(myarr,myarr+7);
int myin;
vector< vector<int> > myout;
Solution SA;
cout << "Please Enter" << endl;
cin >> myin;
myout = SA.fourSum(myin1,myin);
cout<<"VecOUT:"<<myout.size()<<endl;
for(unsigned int i = 0; i < myout.size(); i++){
for(vector<int>::iterator itt = myout[i].begin() ;itt!=myout[i].end(); itt++){
cout<<*itt<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<endl;
return 0;
}
LeetCode 遍历技巧 | 18. 4Sum
最新推荐文章于 2022-02-27 14:50:19 发布
本文介绍了解决LeetCode 18题四数之和问题的算法思路与实现细节,通过双指针技巧实现了O(n^2)时间复杂度的解决方案,并详细解释了如何去除重复结果。
862

被折叠的 条评论
为什么被折叠?



