All unique triplets that sum up to a given value
Last Updated :
25 May, 2021
Given an array and a sum value, find all possible unique triplets in that array whose sum is equal to the given sum value. If no such triplets can be formed from the array, then print “No triplets can be formed”, else print all the unique triplets. For example, if the given array is {12, 3, 6, 1, 6, 9} and the given sum is 24, then the unique triplets are (3, 9, 12) and (6, 6, 12) whose sum is 24.
Examples:
Input : array = {12, 3, 6, 1, 6, 9} sum = 24
Output : [[3, 9, 12], [6, 6, 12]]
Input : array = {-2, 0, 1, 1, 2} sum = 0
Output : [[-2, 0, 2], [-2, 1, 1]]
Input : array = {-2, 0, 1, 1, 2} sum = 10
Output : No triplets can be formed
Method 1
In a previous post, Find a triplet that sum to a given value we have discussed whether the triplets can be formed from the array or not.
Here we need to print all unique set of triplets that sum up to a given value
- Sort the input array.
- Find three indexes from the array i, j and k where A[i]+A[j]+A[k] = given sum value.
- Fix the first element as A[i] and iterate i from 0 to array size – 2.
- For each iteration of i, take j to be index of the first element in the remaining elements and k to be the index of the last element.
- Check for the triplet combination A[i]+A[j]+A[k] = given sum value.
- If triplet is obtained (ie., A[i]+A[j]+A[k] = given sum value)
- Add all the triplet in a TreeSet with “:” separated value to get the unique triplets.
- Increment the second value index
- Decrement the third value index.
- Repeat step 4 & 5 till j < k
- Else if, A[i]+A[j]+A[k] < given sum value, increment the second value index
Else if, A[i]+A[j]+A[k] > given sum value, decrement the third value index
Below is the implementation of the above idea:
C++
#include <bits/stdc++.h>
using namespace std;
struct triplet
{
int first, second, third;
};
int findTriplets( int nums[], int n, int sum)
{
int i, j, k;
vector<triplet> triplets;
unordered_set<string> uniqTriplets;
string temp;
triplet newTriplet;
sort(nums, nums + n);
for (i = 0; i < n - 2; i++)
{
j = i + 1;
k = n - 1;
while (j < k) {
if (nums[i] + nums[j] + nums[k] == sum)
{
temp = to_string(nums[i]) + " : "
+ to_string(nums[j]) + " : "
+ to_string(nums[k]);
if (uniqTriplets.find(temp)
== uniqTriplets.end()) {
uniqTriplets.insert(temp);
newTriplet.first = nums[i];
newTriplet.second = nums[j];
newTriplet.third = nums[k];
triplets.push_back(newTriplet);
}
j++;
k--;
}
else if (nums[i] + nums[j] + nums[k] > sum)
k--;
else
j++;
}
}
if (triplets.size() == 0)
return 0;
for (i = 0; i < triplets.size(); i++) {
cout << "[" << triplets[i].first << ", "
<< triplets[i].second << ", "
<< triplets[i].third << "], " ;
}
}
int main()
{
int nums[] = { 12, 3, 6, 1, 6, 9 };
int n = sizeof (nums) / sizeof (nums[0]);
int sum = 24;
if (!findTriplets(nums, n, sum))
cout << "No triplets can be formed." ;
return 0;
}
|
Java
import java.util.*;
public class triplets {
public static List<List<Integer> >
findTriplets( int [] nums, int sum)
{
Arrays.sort(nums);
List<List<Integer> > pair
= new ArrayList<>();
TreeSet<String> set
= new TreeSet<String>();
List<Integer> triplets
= new ArrayList<>();
for ( int i = 0 ;
i < nums.length - 2 ;
i++) {
int j = i + 1 ;
int k = nums.length - 1 ;
while (j < k) {
if (nums[i] + nums[j]
+ nums[k] == sum) {
String str
= nums[i] + ":" + nums[j]
+ ":" + nums[k];
if (!set.contains(str))
{
triplets.add(nums[i]);
triplets.add(nums[j]);
triplets.add(nums[k]);
pair.add(triplets);
triplets = new ArrayList<>();
set.add(str);
}
j++;
k--;
}
else if (nums[i]
+ nums[j]
+ nums[k] < sum)
j++;
else
k--;
}
}
return pair;
}
public static void main(String[] args)
{
int [] nums = { 12 , 3 , 6 , 1 , 6 , 9 };
int sum = 24 ;
List<List<Integer> > triplets
= findTriplets(nums, sum);
if (!triplets.isEmpty()) {
System.out.println(triplets);
}
else {
System.out.println( "No triplets can be formed" );
}
}
}
|
Python3
def findTriplets(nums, n, Sum ):
i = 0
j = 0
k = 0
triplet = []
uniqTriplets = []
temp = ""
newTriplet = [ 0 , 0 , 0 ]
nums.sort()
for i in range (n - 2 ):
j = i + 1
k = n - 1
while (j < k):
if (nums[i] + nums[j] + nums[k] = = Sum ):
temp = str (nums[i]) + ":" + str (nums[j]) + ":" + str (nums[k])
if temp not in uniqTriplets:
uniqTriplets.append(temp)
newTriplet[ 0 ] = nums[i]
newTriplet[ 1 ] = nums[j]
newTriplet[ 2 ] = nums[k]
triplet.append(newTriplet)
newTriplet = [ 0 , 0 , 0 ]
j + = 1
k - = 1
elif (nums[i] + nums[j] + nums[k] > Sum ):
k - = 1
else :
j + = 1
if ( len (triplet) = = 0 ):
return 0
for i in range ( len (triplet)):
print (triplet[i], end = ", " )
return 1
nums = [ 12 , 3 , 6 , 1 , 6 , 9 ]
n = len (nums)
Sum = 24
if ( not findTriplets(nums, n, Sum )):
print ( "No triplets can be formed." )
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static List<List< int >>
findTriplets( int [] nums, int sum)
{
Array.Sort(nums);
List<List< int > > pair
= new List<List< int > >();
SortedSet<String> set
= new SortedSet<String>();
List< int > triplets
= new List< int >();
for ( int i = 0;
i < nums.Length - 2;
i++) {
int j = i + 1;
int k = nums.Length - 1;
while (j < k) {
if (nums[i]
+ nums[j]
+ nums[k] == sum) {
String str
= nums[i] + ":" + nums[j]
+ ":" + nums[k];
if (! set .Contains(str))
{
triplets.Add(nums[i]);
triplets.Add(nums[j]);
triplets.Add(nums[k]);
pair.Add(triplets);
triplets = new List< int >();
set .Add(str);
}
j++;
k--;
}
else if (nums[i]
+ nums[j]
+ nums[k] < sum)
j++;
else
k--;
}
}
return pair;
}
public static void Main(String[] args)
{
int [] nums = { 12, 3, 6, 1, 6, 9 };
int sum = 24;
List<List< int > > triplets
= findTriplets(nums, sum);
if (triplets.Count != 0) {
Console.Write( "[" );
for ( int i = 0; i < triplets.Count; i++)
{
List< int > l = triplets[i];
Console.Write( "[" );
for ( int j = 0; j < l.Count; j++)
{
Console.Write(l[j]);
if (l.Count != j + 1)
Console.Write( ", " );
}
Console.Write( "]" );
if (triplets.Count != i + 1)
Console.Write( "," );
}
Console.Write( "]" );
}
else
{
Console.WriteLine( "No triplets can be formed" );
}
}
}
|
Javascript
<script>
function findTriplets(nums,sum)
{
nums.sort( function (a,b){ return a-b;});
let pair = [];
let set = new Set();
let triplets= [];
for (let i = 0;
i < nums.length - 2;
i++)
{
let j = i + 1;
let k = nums.length - 1;
while (j < k) {
if (nums[i] + nums[j]
+ nums[k] == sum) {
let str= nums[i] + ":" + nums[j]
+ ":" + nums[k];
if (!set.has(str))
{
triplets.push(nums[i]);
triplets.push(nums[j]);
triplets.push(nums[k]);
pair.push(triplets);
triplets =[];
set.add(str);
}
j++;
k--;
}
else if (nums[i]
+ nums[j]
+ nums[k] < sum)
j++;
else
k--;
}
}
return pair;
}
let nums=[12, 3, 6, 1, 6, 9];
let sum = 24;
let triplets
= findTriplets(nums, sum);
if (triplets.length!=0) {
document.write( "[" );
for (let i = 0; i < triplets.length; i++)
{
let l = triplets[i];
document.write( "[" );
for (let j = 0; j < l.length; j++)
{
document.write(l[j]);
if (l.length != j + 1)
document.write( ",  " );
}
document.write( "]" );
if (triplets.length != i + 1)
document.write( ", " );
}
document.write( "]" );
}
else {
document.write( "No triplets can be formed" );
}
</script>
|
Output
[3, 9, 12], [6, 6, 12],
Time Complexity: O(n2)
Space Complexity: O(n)
Method 2
In this method, we will see another way to solve this problem which will use only a constant amount of space. Here in this method, we would check if the current element is the same as the previous one then we will not consider it and just simply skip that element. By using this we will be able to find only unique triplets only.
Algorithm
- Sort the input array.
- For the first element iterate i from 0 to n-2.
- For each iteration we will have two indexes starts and end where the start would be equal to i+1 and end would be equal to n-1.
- Now we will look for a target whose value is sum-a[i] in the range from start to end using two pointer techniques.
- In this we will look for the previous elements if they are the same then we would not work for them to find all unique duplicates.
- If we found target==a[start]+a[end] then we would print it and increment start and decrement end.
- If target>a[start]+a[end] then we would increment start.
- Else we would decrement end
Below is the implementation of the above idea:
C++
#include <bits/stdc++.h>
using namespace std;
void findTriplets( int a[], int n, int sum)
{
int i;
sort(a, a + n);
bool flag = false ;
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
int start = i + 1;
int end = n - 1;
int target = sum - a[i];
while (start < end)
{
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue ;
}
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue ;
}
if (target == a[start] + a[end])
{
cout << "[" << a[i]
<< "," << a[start]
<< "," << a[end] << "] " ;
flag = true ;
start++;
end--;
}
else if (target > (a[start] + a[end]))
{
start++;
}
else {
end--;
}
}
}
}
if (flag == false ) {
cout << "No Such Triplets Exist"
<< "\n" ;
}
}
int main()
{
int a[] = { 12, 3, 6, 1, 6, 9 };
int n = sizeof (a) / sizeof (a[0]);
int sum = 24;
findTriplets(a, n, sum);
return 0;
}
|
Java
import java.util.*;
public class Main
{
public static void findTriplets( int a[], int n, int sum)
{
int i;
Arrays.sort(a);
boolean flag = false ;
for (i = 0 ; i < n - 2 ; i++)
{
if (i == 0 || a[i] > a[i - 1 ])
{
int start = i + 1 ;
int end = n - 1 ;
int target = sum - a[i];
while (start < end)
{
if (start > i + 1
&& a[start] == a[start - 1 ])
{
start++;
continue ;
}
if (end < n - 1
&& a[end] == a[end + 1 ])
{
end--;
continue ;
}
if (target == a[start] + a[end])
{
System.out.print( "[" + a[i]
+ "," + a[start]
+ "," + a[end] + "] " );
flag = true ;
start++;
end--;
}
else if (target > (a[start] + a[end]))
{
start++;
}
else {
end--;
}
}
}
}
if (flag == false ) {
System.out.print( "No Such Triplets Exist" );
}
}
public static void main(String[] args) {
int a[] = { 12 , 3 , 6 , 1 , 6 , 9 };
int n = a.length;
int sum = 24 ;
findTriplets(a, n, sum);
}
}
|
Python3
def findTriplets(a, n, sum ):
a.sort()
flag = False
for i in range (n - 2 ):
if (i = = 0 or
a[i] > a[i - 1 ]):
start = i + 1
end = n - 1
target = sum - a[i]
while (start < end):
if (start > i + 1 and
a[start] = = a[start - 1 ]):
start + = 1
continue
if (end < n - 1 and
a[end] = = a[end + 1 ]):
end - = 1
continue
if (target = = a[start] + a[end]):
print ( "[" , a[i], "," ,
a[start], "," ,
a[end], "]" ,
end = " " )
flag = True
start + = 1
end - = 1
elif (target >
(a[start] + a[end])):
start + = 1
else :
end - = 1
if (flag = = False ):
print ( "No Such Triplets Exist" )
if __name__ = = "__main__" :
a = [ 12 , 3 , 6 , 1 , 6 , 9 ]
n = len (a)
sum = 24
findTriplets(a, n, sum )
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void findTriplets( int [] a, int n, int sum)
{
int i;
Array.Sort(a);
bool flag = false ;
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
int start = i + 1;
int end = n - 1;
int target = sum - a[i];
while (start < end)
{
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue ;
}
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue ;
}
if (target == a[start] + a[end])
{
Console.Write( "[" + a[i]
+ "," + a[start]
+ "," + a[end] + "] " );
flag = true ;
start++;
end--;
}
else if (target > (a[start] + a[end]))
{
start++;
}
else {
end--;
}
}
}
}
if (flag == false ) {
Console.WriteLine( "No Such Triplets Exist" );
}
}
static void Main() {
int [] a = { 12, 3, 6, 1, 6, 9 };
int n = a.Length;
int sum = 24;
findTriplets(a, n, sum);
}
}
|
Javascript
<script>
function findTriplets(a, n, sum)
{
let i;
a.sort( function (a, b){ return a - b});
let flag = false ;
for (i = 0; i < n - 2; i++)
{
if (i == 0 || a[i] > a[i - 1])
{
let start = i + 1;
let end = n - 1;
let target = sum - a[i];
while (start < end)
{
if (start > i + 1
&& a[start] == a[start - 1])
{
start++;
continue ;
}
if (end < n - 1
&& a[end] == a[end + 1])
{
end--;
continue ;
}
if (target == a[start] + a[end])
{
document.write( "[" + a[i]
+ "," + a[start]
+ "," + a[end] + "] " );
flag = true ;
start++;
end--;
}
else if (target > (a[start] + a[end]))
{
start++;
}
else {
end--;
}
}
}
}
if (flag == false ) {
document.write( "No Such Triplets Exist" );
}
}
let a = [ 12, 3, 6, 1, 6, 9 ];
let n = a.length;
let sum = 24;
a.sort();
findTriplets(a, n, sum);
</script>
|
Complexity Analysis:
- Time Complexity: O(n2).
Since two nested loops is required, so the time complexity is O(n2).
- Auxiliary Space: O(1).
Since we need no extra space for solving this.
Please Login to comment...