[C + +] leetcode:71 4Sum && ksum Summary __c++

Source: Internet
Author: User

topic:

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:
Elements in a quadruplet (a,b,c,d) must being in the 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)

Answer 1: Common law degradation to 2Sum problem

There is a blog detailing the ksum problem: Summary for Leetcode 2Sum, 3Sum, 4Sum, K Sum

K Sum Summary:

k sum problem description: give you a set of n numbers (such as vector<int> num), and then give you a constant (such as int target), our goal is in this heap number to find K number, Makes the sum of these k numbers equal to target.

Precautions :

1. Remove Duplicates.

Note that this set of numbers may have duplicates: for example 1 1 2 3, 3sum, then target = 6, you may get two groups of 1 2 3, 1 2 3,1 from the first 1 or the second 1, but the result is only one group, so the final result is to go heavy.

2. Note the extent of the degradation process by determining the number of previous k-2.

For example, the 3Sum problem, the first number of the range is 0~num.size ()-2. Because after we have sorted out, we just need to detect the last third number, because only one triplet is left in the final three digits. Other k sum issues similar to the scoping.

solution: First sort after the pinch, the k sum problem degenerate to k-1 sum problem, eventually degenerate to 2Sum problem. Then use the tail pointer to find two numbers to make their sum equal to the new target.

give the core code for 2 sum:

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" >//2 sum int i = starting; Head pointer Int j = num.size ()-1;

    Tail pointer while (I < j) {int sum = Num[i] + num[j];
        if (sum = = target) {store num[i] and num[j] somewhere;
        If (we need only one such pair of the numbers) break;
    Otherwise do ++i,--j;
    else if (sum < target) ++i;
else--j; }<strong> </strong></span></span></span> 
The 2sum algorithm complexity is O (n log n) because the sort uses n log n and the search of the tail pointer is linear, so the overall is O (n log n), OK now consider 3sum, with 2sum actually 3sum is not difficult, so think: First Take out a number, So I just need to find two numbers in the remaining numbers so that their sum equals (target– that number taken out). So the 3sum degenerated into 2sum, take out a number, such numbers have N, so the 3sum algorithm complexity is O (n^2), note that the complexity here is N squared, because you sort of only have to row once, the back of the work is to take out a number, and then find the remaining two digits, Looking for two digits is 2sum with the tail-pointer linear sweep, where it is easy to mistake the complexity into O (n^2 log N), this is wrong. As we go on, 4sum can degenerate into a 3sum problem (copyright @sigmainfy), and so on and so on, K-sum, and finally to solve a 2sum problem, the complexity of K sum is O (n^ (K-1)). This sector seems to be the best of the world, that is, the k-sum problem is best to do O (n^ (K-1)) complexity, before you have seen some people say that can be strictly mathematical proof, here is not in-depth study.
AC Code: (4 Sum)

Note: Note that the first and second numbers determine the starting and ending ranges.

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;"
        >class Solution {public:vector<vector<int> > Foursum (vector<int> &num, int target) {
        vector<vector<int>> ret;
        if (Num.size () < 4) return RET;
        int n = num.size ();
        vector<int> Ivec (num);
        
        Sort (Ivec.begin (), Ivec.end ()); for (int i = 0; i < n-3;i++)//(1) Trick 1 determines the range to the penultimate fourth number {if (i > 0 && ivec[i] = = ivec[  I-1]) continue;  Prevent first digit repeat (2) Trick 2 avoid duplicates for (int j = i+1 J < n-2;j++) {if (J > i + 1  && Ivec[j] = = Ivec[j-1]) continue;
                prevent second digit repeat int newtarget = target-ivec[i]-ivec[j];
                int k = j + 1;
                
                int L = n-1;
         while (K < L) {if (Ivec[k] + ivec[l] = = newtarget)           {vector<int> tmp{ivec[i], ivec[j], ivec[k], ivec[l]};                    Ret.push_back (TMP);
                        Trick 3 skips over duplicates do{k++;
                        }while (K < l && ivec[k] = = ivec[k-1]);
                        do{l--;
                    }while (K < l && ivec[l] = = ivec[l+1]);
                    else if (Ivec[k] + ivec[l] > Newtarget) {l--;
                    else {k++;
    }}} return ret; }};</span></span></span>

Answer 2:hash Method

idea: O (n^2) algorithm, and the previous equivalent, are sorted first by the array. Let's first enumerate all two numbers and store them in a hash map, where the key of the map corresponds to the sum of two digits, because the summation of the multiple pairs of elements may be the same value, so the value of the hash map is a list (the following code is substituted with an array), and each node in the list contains the two numbers in the subscript of the array. The time complexity of this preprocessing is O (n^2). Then, like algorithm 1, enumerate the first and second elements, assuming that they are v1,v2, and then look up all two-dollar pairs (in the corresponding list) for TARGET-V1-V2 in the hash map, and find the time O (1), in order to ensure that the computations are not repeated, We only keep two-digit subscript is greater than the V2 two-dollar pair (in fact, we in the previous 3sum problem in the three number of numbers in the order after the array of the lower subscript are incremented), this is also possible to repeat: for example, after the sequence is -9-4-2 0 2 4 4,target = 0, when the first and second elements are -4,-2, we want to get and be 0-(-2)-(-4) = 6-dollar pairs, such two-dollar pairs have two, are (2,4), and their subscript in the array are greater than-4 and-2, if all add results, then ( -4,-2,2,4) will appear two times, So when you add a two-dollar pair, you have to decide whether to repeat the two-dollar pairs that have been added (since the array has been ordered before the early two-dollar pair, so two elements are the same two-dollar pairs can be guaranteed in the list is adjacent, the list does not appear (2,4)-> (1,5)-> (2,4), So just judge whether the newly added two-dollar pair and the last added two-dollar pair are repeated, because the same list of two is the same as the two elements, so as long as the two-dollar pair has a different element, the two-dollar pair is different. We can see that the key of the hash map has a constant chain length, so the total complexity of the algorithm is O (n^2)

Attention:

1. If you want the same pair to be stored in a linked list, you can construct a map of value for the array.

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" > Unordered_map<int, vector<pair<int,int> > > pairs;</span></span></span>
2. Initialize map, store 22 of the and. Note that J starts with i+1, otherwise it sums up the sum of itself.

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" >for (int i = 0; i < n; i++) for
       (int j = i+1; J < N; j +)
             Pairs[num[i]+num[j]].push_back (Make_pair (i,j)); </span></span></span>
3. The means of removing repetition is similar to that of 3Sum.

4. In response to the pair problem, we also need to find compliance with the subscript increment requirements, and can not have duplicate number added (to determine whether the third position is consistent).

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" >bool Isfstpush = true;
The pair that meets the requirements for a repeat and subscript increment is saved in the answer for
 (int k = 0; k < sum2.size (); k++)
{
    if (Sum2[k].first <= j) continue;
    The first time a duplicate number is stored, or not a repeat number, to determine if the third digit is equal if
    (Isfstpush | | (Ret.back ()) [2]!= Ivec[sum2[k].first]) {...} </span></span></span>

5. Note the use of pair operations and arrays to invoke the number of the original array.

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" > vector<int> tmp{ivec[i], ivec[j], Ivec[sum2[k].first], Ivec[sum2[k].second]}; </span></span></span>

6.Reserve function:

The vector is preconfigured with the storage size, which is the value of the capacity, but the memory is not initialized. Reserve's parameter n is the recommended amount of preconfigured memory, the actual allocation may be equal to or greater than this value, that is, N is greater than the actual allocation of space value, will reallocate memory (the actual allocation of space value) capacity value will be greater than or equal to N. This avoids the memory reallocation overhead when Ector calls the Push_back function to make the size exceed the original default allocated capacity value.

Note that the reserve function allocates memory space only to indicate that the vector can take advantage of this part of memory, but the vector does not have access to the memory space effectively (before the object is created, the elements in the container cannot be referenced), the access occurs when there is a cross-border phenomenon, causing the program to crash.

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;" > Pairs.reserve (n*n);</span></span>
AC Code:

<span style= "FONT-SIZE:14PX;" ><span style= "FONT-SIZE:14PX;"
        >class Solution {public:vector<vector<int> > Foursum (vector<int> &num, int target) {
        int n = num.size ();
        vector<vector<int> > ret;
        if (n < 4) return RET;
        vector<int> Ivec (num);
        Sort (Ivec.begin (), Ivec.end ());
        Unordered_map<int, vector<pair<int,int> > > pairs;
        
        Pairs.reserve (N*n); The pairs of 22 combinations of n digits are stored in the map in accordance with the linked list, that is, the presence of J from I+1 for (int i = 0; i < n; i++) {for T j = i+1; J < N;
            J + +) {Pairs[ivec[i] + ivec[j]].push_back (Make_pair (i,j)); for (int i = 0; i < n-3 i++) {if (i > 0 && ivec[i] = = Ive
            C[I-1]) continue; for (int j = I+1 J < N-2 + +) {if (J > i+1 && ivec[j] = = ivec[j-1]) conTinue; if (Pairs.find (Target-ivec[i]-ivec[j])!= pairs.end ()) {vector<pair<int, int
                    > > sum2 = pairs[target-ivec[i]-ivec[j]];
                    bool Isfstpush = true;
                        Pair the answer for (int k = 0; k < sum2.size (); k++), which conforms to the required repeat and subscript increments
                        if (Sum2[k].first <= j) Continue; The first time a duplicate number is stored, or not a repeat number, to determine if the third digit is equal if (Isfstpush | | (Ret.back ()) [2]!= Ivec[sum2[k].first]) {vector<int> tmp{ivec[i], ivec[j], I 
                           Vec[sum2[k].first], Ivec[sum2[k].second]};
                           Ret.push_back (TMP);
                        Isfstpush = false;
    }}} return ret; }};</span></span>



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.