find all unique triplet in given array with sum zero

Feb 26, 2015 at 12:34pm
Hello to all of you...
I got all unique triplet from below code but I want to reduce its time complexity.
It consist three for loop. So my question is, Is it possible to do in minimum loop that it decrease its time complexity. code will be execute in minimum time.
Thanks in advanced let me know.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <cstdlib>
#include<iostream>
using namespace std;
void Triplet(int[], int, int); 
void Triplet(int array[], int n, int sum)
{
   // Fix the first element and find other two
     for (int i = 0; i < n-2; i++)
     {
        // Fix the second element and find one
 	       for (int j = i+1; j < n-1; j++)
        {
           // Fix the third element
           for (int k = j+1; k < n; k++)
           if (array[i] + array[j] + array[k] == sum)
            cout << "Result :\t" << array[i] << " + " << array[j] << " + " << array[k]<<" = " << sum << endl;
         }
      }
 }

int main()
{
    int A[] = {-10,-20,30,-5,25,15,-2,12};
    int sum = 0;
    int arr_size = sizeof(A)/sizeof(A[0]);
    cout<<"********************O(N^3) Time Complexity*****************************"<<endl;
    Triplet(A,arr_size,sum);
    return 0;
}
Feb 26, 2015 at 1:11pm
If it is possible to change your array, there is obvious fix for your algorithm: sort array first , then search for triplets. You already know what third value should be if you know first two, so you can just test for its existence in array by binary search. O(N^2 logN)

Also you can apply some knowledge on resulting triplet: for example that there should be both negative and positive value here, so you can choose first two values to be of different signs. This will not reduce complexivity, but will improve execution time.
Feb 26, 2015 at 1:16pm
the algorithm below first sorts the input array and then tests all possible pairs in a careful order that avoids the need to binary search for the pairs in the sorted list, achieving worst-case O(n^2) time
https://en.wikipedia.org/wiki/3SUM#Quadratic_algorithm
Feb 27, 2015 at 4:48am
Thank you so muxh thanx to all.. i ll try with this and get back to you..
Feb 27, 2015 at 4:55am
@Miinipaa:- Actually I have already tried with your solution but it will give only two pairs not all unique pair.
Feb 27, 2015 at 5:36am
@JLBorges:-
Hi , i hav tried your soltuion but it still give only two triplet.I want all unique triplet so what should i do.? please let me know.
Feb 27, 2015 at 8:12am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <vector>
#include <tuple>
#include <set>
#include <algorithm>

std::set< std::tuple<int,int,int> > unique_zero_3sum_tuples( std::vector<int> seq )
{
    std::set< std::tuple<int,int,int> > tuples ;

    const int n = seq.size() ;
    if( n > 2 )
    {
        sort( seq.begin(), seq.end() ) ;
        const int end = n - 2 ;

        for( int first = 0 ; first < end && seq[first] < 1 ; ++first )
        {

            int second = first + 1 ;
            int third = end + 1 ;

            while( second < third )
            {
                int sum = seq[first] + seq[second] + seq[third] ;

                if( sum == 0)
                {
                    tuples.insert( std::make_tuple( seq[first], seq[second], seq[third] ) ) ;
                    ++second ;
                    --third ;
                }

                else if( sum > 0 ) --third ;

                else ++second ; // sum < 0
            }
        }
    }

    return tuples ;
}

void print_unique_zero_3sum_triplets( std::vector<int> seq )
{
    for( const auto& tup : unique_zero_3sum_tuples(seq) )
        std::cout << std::get<0>(tup) << ' ' << std::get<1>(tup) << ' ' << std::get<2>(tup) << '\n' ;
}

int main()
{
    print_unique_zero_3sum_triplets( { -10, -10, -20, -20, 30, 30, -5, 25, 15, 15, -2, 12, 12 } ) ;
    std::cout << "------------------------\n" ;
    print_unique_zero_3sum_triplets( { -25, -10, -7, -3, 1, 2, 3, 4, 5, 8, 10, 13, 15, 17, 28, -10, -7, -3, 1, 2 } ) ;
}

http://coliru.stacked-crooked.com/a/95f631e92edcba36
Feb 27, 2015 at 12:04pm
Thanx JLBorges.. I ll go with it.
Topic archived. No new replies allowed.