Given an array S of n integers, is 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:
- Elements in a quadruplet (a,b,c,D) must is in non-descending order. (ie, a ≤ b ≤ c ≤ d)
- 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)
Idea: To use the method of 3Sum, plus a For loop, Time complexity O (N3), the result is when limit exceeded
classSolution { Public: Vector<vector<int>> Foursum (vector<int>& Nums,inttarget) { intSize =nums.size (); if(Size <3)returnresult; Sort (Nums.begin (), Nums.end ()); for(inti =0; I < size-3; i++){ if(I >0&& nums[i]==nums[i-1])Continue; for(intj = i+1; J < size-2; J + +){ if(J> i+1&& nums[j]==nums[j-1])Continue; Find (Nums, J+1, size-1,-nums[i]-Nums[j], I, j); } } returnresult; } voidFind (vector<int>& Nums,intStartintEndintTargetint& Index1,int&index2) { intsum; while(start<end) {Sum= nums[start]+Nums[end]; if(Sum = =target) {item.clear (); Item.push_back (Nums[index1]); Item.push_back (Nums[index2]); Item.push_back (Nums[start]); Item.push_back (Nums[end]); Result.push_back (item); Do{Start++; } while(start!= end && Nums[start] = = nums[start-1]); Do{End--; } while(End!=start && nums[end] = = nums[end+1]); } Else if(sum>target) { Do{End--; } while(End!=start && nums[end] = = nums[end+1]); } Else{ Do{Start++; } while(start!= end && Nums[start] = = nums[start-1]); } } } Private: Vector<vector<int>>result; Vector<int>item;};
Use hash table. O (n^2) put all the pair into a hash table, and the two elements of the pair is the hash value. Then the next 4sum becomes the 2sum in all the pair value, this becomes the linear algorithm. So on the whole this algorithm is O (n^2) +o (N) = O (n^2).
classSolution { Public: Vector<vector<int>> Foursum (vector<int>& Nums,inttarget) { intSize =nums.size (); intA, B, C, D; Vector<vector<int>>result; Unordered_map<int,vector<pair<int,int> > >MP; Unordered_map<int,int> cnt;//the number of each number if(Size <3)returnresult; Sort (Nums.begin (), Nums.end ()); for(inti =0; I < size-1; i++){ if(I >0&& nums[i]==nums[i-1])Continue; for(intj = i+1; J < size; J + +){ if(J> i+1&& nums[j]==nums[j-1])Continue; Mp[nums[i]+nums[j]].push_back (pair<int,int>{nums[i],nums[j]}); } } for(inti =0; i < size; i++) {Cnt[nums[i]]++; } for(unordered_map<int,vector<pair<int,int> > >::iterator it1=mp.begin (); It1!=mp.end (); it1++) {//Traverse Mapunordered_map<int,vector<pair<int,int> > >::iterator it2=mp.find (Target-it1->first);//Find a map if(It2==mp.end ())Continue;//Not found if(It1->first > It2->first)Continue;//already checked, go to heavy for(inti =0; I < it1->second.size (); i++) {//accessing the Map element for(intj =0; J < It2->second.size (); J + +) {a= it1->second[i].first;//accessing the pair elementb = it1->Second[i].second; C= it2->Second[j].first; D= it2->Second[j].second; if(max (b) > min (c,d))Continue;//four number of 22 combinations, with 6 cases, where only two minimum numbers are taken in the case of the it1, to remove the weightcnt[a]--; CNT[B]--; CNT[C]--; CNT[D]--; if(cnt[a]<0|| cnt[b]<0|| cnt[c]<0|| cnt[d]<0) {Cnt[a]++; CNT[B]++; CNT[C]++; CNT[D]++; Continue; } Cnt[a]++; CNT[B]++; CNT[C]++; CNT[D]++; Vector<int> tmp ={a,b,c,d}; Sort (Tmp.begin (), Tmp.end ()); Result.push_back (TMP); } } } returnresult; }};
18.4Sum (HashTable)