Topic:
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)
Analysis: Given an array of n numbers, ask if there are four number ABCD in the array, making a+b+c+d = target. Finds all of the four-digit sets that match the criteria in the array. Each set is required not to repeat, and ABCD is arranged from small to large. Method of three:
1. First sort, then left and right clamp, time complexity O (n^3), Space complexity O (1)
2. Sort and then cache two number of and, finally, traverse.
3. Sort first, then cache two number of and then on these and proceed 2sum. Requires unequal coordinates.
Code:
#include "stdafx.h" #include <ctime>
#include <iostream> #include <vector> #include <algorithm> #include <unordered_map>using namespace stdext;using namespace Std;
Class solution{public:vector< vector<int> > FourSum1 (vector<int>& num, int target) {vector< Vector<int>> result;vector<int> Temp (4), Sort (Num.begin (), Num.end ()), Auto last = Num.end (); for (Auto a = Num.begin (); A! = Last-3;++a) {for (auto B = Next (a); B! = prev (last,2); ++b) {Auto c = next (b), auto d = prev (last), while (c &L T D) {if (*a + *b + *c + *d < target) {C + +;} else if (*a + *b + *c + *d >target) {d--;} Else{temp[0]=*a; Temp[1]=*b;temp[2]=*c; Temp[3]=*d;result.push_back (temp); ++c;--d;}}} Sort (Result.begin (), Result.end ()),//unique removes the adjacent repeating element, and then returns a new trailing pointer, erase erasing the excess memory portion. Result.erase (Unique (Result.begin (), Result.end ()), Result.end ()), return result; vector< vector<int> > FourSum2 (vector<int>& num, int target) {vector<vector<int>> Result;if (Num.size () < 4) return result;vector<int> temp (4); sort (Num.begin (), Num.end ());unordered_map< int, vector<pair<int, int>> > twosum; Duplicate key values that are stored in a vectorAuto last = Num.end (), for (size_t a=0;a<num.size (), ++a) {for (size_t B = a+1;b<num.size (); ++b) {Twosum[num[a] + num[b ]].push_back (pair<int,int> (Num[a],num[b));}} int sub = 0;for (size_t c=0;c<num.size (); ++c) {for (size_t d=c+1;d<num.size (); ++d) {sub = Target-num[c]-num[d];if (t Wosum.find (sub) = = Twosum.end ()) continue;auto& Subrst = twosum[sub];//may have multiple results. For (size_t i=0;i<subrst.size (); ++i) {if (Num[c] <= Subrst[i].first | | num[d] <= subrst[i].second)//Remove duplicates, The elements in the pair are sorted from small to large, so secondcontinue;temp[0] = subrst[i].first;temp[1] = subrst[i].second;temp[2] = num[c];temp[3] = num[d] ; Sort (Temp.begin (), Temp.end ()); Result.push_back (temp);}}} Sort (Result.begin (), Result.end ()), Result.erase (Unique (Result.begin (), Result.end ()), Result.end ()), return result; vector< vector<int> > FourSum3 (vector<int>& num, int target) {vector<vector<int>> Result;if (Num.size () < 4) return result;vector<int> temp (4); sort (Num.begin (), Num.end ()); Unordered_multimap< int,pair<int, int> > twosum;for (size_t i = 0;i<num.size (); ++i) {for (size_t j=i+1;j< Num.size (); ++j) {Twosum.insert (Make_pair (num[i]+ num[j], Make_pair (Num[i],num[j]));}} for (auto I=twosum.begin (); I!=twosum.end (), ++i) {int sub = Target-i->first;auto Range = Twosum.equal_range (sub); for ( Auto j=range.first;j!=range.second;++j) {pair<int,int> k = I->second;int a = k.first; int b = K.second;int c = j-& Gt;second.first;int d = j->second.second;if (a!=c && a!=d && b! = C && b!=d) {temp[0] = a;temp[1] = b;temp[2] = c;temp[3] = D;sort (Temp.begin (), Temp.end ()); Result.push_back (temp);}}} Sort (Result.begin (), Result.end ()), Result.erase (Unique (Result.begin (), Result.end ()), Result.end ()); return result;}; int _tmain (int argc, _tchar* argv[]) {vector<int> v1;vector<vector<int>> result;v1.push_back (1); V1.push_back (0); V1.push_back ( -1); v1.push_back (0); V1.push_back ( -2); V1.push_back (2);//v1.push_back (rand ()%200- (V1.pus));H_back (rand ()%200-100)); Solution s;clock_t Start,finish;long i = 100000l;double Duration;start = clock (); result = S.foursum1 (v1,0); finish = Clock ( );d uration = (double) (Finish-start)/clocks_per_sec;cout<< "FourSum1 Runtime:" << duration << Endl; start = Clock (), result = S.foursum2 (v1,0), finish = Clock ();d uration = (double) (Finish-start)/clocks_per_sec;cout<& Lt "FourSum2 Runtime:" << duration << Endl;start = clock (); result = S.FOURSUM3 (v1,0); finish = Clock ();d uration = (double) (Finish-start)/clocks_per_sec;cout<< "FourSum3 Runtime:" << duration << Endl;return 0;}
Summary:
It is worthwhile to study a topic, it is recommended to write it over, not only for the improvement of algorithm ideas, but also in the use of STL learning, it is helpful. According to my test, in terms of run time, the method is the fastest, second, and three slowest.
In addition, method two experiment unordered_map, where the key value is identical, the value of the same key is stored in a vector bucket. And method three uses unordered_multimap, when existence key same situation, is not like the former storage, but separate storage.
For example: Unordered_map in the form of: [1] = (-2, [2] ((-2, 0), (-2, 0))) The same key values are put together. Duplicate key values are not allowed.
Unordered_multimap in the form of: (-2, (-2, 0)), (-2, (-2, 0)) Although the key values are different, but are stored separately. Duplicate key values are allowed.
Leetcode 4Sum (Classic)