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. Note: The solution set must not contain duplicate quadruplets. For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
题目说给一串存在重复的数组,要找出里面是否有这样的四个数使得 a+b+c+d = target
首先想到有序能够帮助查找这两个数。
然后先抓住两个数,嗯一开始我想通过一个数组直接哈希保存这个数组中两两相加的结果,然后根据抓住的两个数hashNum[target-nums[i]-nums[j]]就可以知道抓住的这两个数存不存在解。然而,因为两两相加会有重复结果,所以这个不利于判断。
又想在hash中保存一个数,然后做三次循环遍历,然而测试数据实在太大了,,数组又只能开到1000000.。
参考了一下别人的,发现数组既然是有序的,那么直接在数组中设两个游标,大了往右游标往左跑,小了左游标往右跑,这样一次循环就能找到所有的了。。。
#include<iostream> #include<vector> #include<set> #include<algorithm> using namespace std; vector<vector<int>> fourSum(vector<int>& nums, int target) { set<vector<int> > s; sort(nums.begin(), nums.end()); for (int i = 0; i < nums.size(); i++) for (int j = i + 1; j < nums.size(); j++) { int begin = j + 1; int end = nums.size() - 1; int temp = target - nums[i] - nums[j]; while (begin<end) { int re = nums[begin] + nums[end]; if (re == temp) { vector<int> num{nums[i], nums[j], nums[begin], nums[end]}; s.insert(num); begin++; } if (re < temp) begin++; else end--; } } vector<vector<int> > result(s.begin(), s.end()); sort(result.begin(),result.end()); return result; } int main(){ vector<int> s{5,0,2,-5,-5,4,-5,1,-1}; vector<vector<int> > re; re=fourSum(s,-5); for(int i=0;i<re.size();i++){ for(int j=0;j<re[i].size();j++){ cout<<re[i][j]<<" "; } cout<<endl; } }
再放一下错误的代码,其中我把set的vector compare 方法重载了。然后其实没必要,C++11中已经对vector的> < = 运算符重载了,直接用就行。
#include<iostream> #include<vector> #include<algorithm> #include<set> #include<string.h> using namespace std; class Cmp{ public: bool operator()(const vector<int>& a,const vector<int>& b){ for(int i=0;i<a.size();i++){ if(a[i]!=b[i]) return a[i]<b[i]; } return false; } }; bool cmp(const vector<int>& a,const vector<int>& b){ for(int i=0;i<a.size();i++){ if(a[i]!=b[i]){ return a[i]<b[i]; } } } vector<vector<int>> fourSum(vector<int>& nums, int target) { #define N 1000000 if(nums.size()==0) { vector<vector<int>> a; return a; } sort(nums.begin(),nums.end()); set<vector<int>, Cmp> s; int index=0; if(nums[0]<0) index = -nums[0]; int numsIs[N]; memset(numsIs,0,sizeof(numsIs)); for(int i=0;i<nums.size();i++){ numsIs[nums[i]+index]++; } int temp; int temp_count; for(int i=0;i<nums.size();i++) for(int j=i+1;j<nums.size();j++) for(int z=j+1;z<nums.size();z++){ temp=target-nums[i]-nums[j]-nums[z]; if(temp>=nums[z] && numsIs[temp+index]>0){ temp_count=numsIs[temp+index]; if(temp==nums[i]) temp_count--; if(temp==nums[j]) temp_count--; if(temp==nums[z]) temp_count--; if(temp_count>0){ vector<int> a; a.push_back(nums[i]); a.push_back(nums[j]); a.push_back(nums[z]); a.push_back(temp); s.insert(a); } } } vector<vector<int> >result(s.begin(),s.end()); sort(result.begin(),result.end(),cmp); return result; } int main(){ int nums[]={5,0,2,-5,-5,4,-5,1,-1}; vector<int> s(nums,nums+9); vector<vector<int> > re; re=fourSum(s,-5); for(int i=0;i<re.size();i++){ for(int j=0;j<re[i].size();j++){ cout<<re[i][j]<<" "; } cout<<endl; } }