3 Sum - Find all Triplets with Given Sum
Last Updated :
20 Oct, 2024
Given an array arr[] and an integer target, the task is to find all possible indices {i, j, k} of triplet {arr[i], arr[j], arr[k]} such that their sum is equal to given target and all indices in a triplet should be distinct (i != j, j != k, k != i). We need to return indices of a triplet in sorted order, i.e., i < j < k.
Examples:
Input: arr[] = {0, -1, 2, -3, 1}, target = -2
Output: {{0, 3, 4}, {1, 2, 3}}
Explanation: Two triplets that add up to -2 are:
arr[0] + arr[3] + arr[4] = 0 + (-3) + (1) = -2
arr[1] + arr[2] + arr[3] = (-1) + 2 + (-3) = -2
Input: arr[] = {1, -2, 1, 0, 5}, target = 1
Output: {}
Explanation: There is no triplet whose sum is equal to 1.
[Naive Approach] Explore all Triplets - O(n^3) Time and O(1) Space
The naive approach is to explore all the triplets using three nested loops and if the sum of any triplet is equal to given target then add it to the result.
C++
// C++ program to find all triplets having sum equal to
// target by exploring all possible triplets
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> findTriplets(vector<int> &arr, int target) {
vector<vector<int>> res;
int n = arr.size();
// Generating all triplets
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
// If the sum of a triplet is equal to target
// then add it's indices to the result
if (arr[i] + arr[j] + arr[k] == target)
res.push_back({i, j, k});
}
}
}
return res;
}
int main() {
vector<int> arr = {0, -1, 2, -3, 1};
int target = -2;
vector<vector<int>> ans = findTriplets(arr, target);
for (int i = 0; i < ans.size(); i++)
cout << ans[i][0] << " " << ans[i][1] << " " <<
ans[i][2] << endl;
return 0;
}
C
// C program to find all triplets having sum equal to
// target by exploring all possible triplets
#include <stdio.h>
void findTriplets(int *arr, int n, int target) {
// Generating all triplets
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
// If the sum of a triplet is equal to target
if (arr[i] + arr[j] + arr[k] == target) {
printf("%d %d %d\n", i, j, k);
}
}
}
}
}
int main() {
int arr[] = {0, -1, 2, -3, 1};
int target = -2;
findTriplets(arr, sizeof(arr) / sizeof(arr[0]), target);
return 0;
}
Java
// Java program to find all triplets having sum equal to
// target by exploring all possible triplets
import java.util.ArrayList;
import java.util.List;
class GfG {
static List<List<Integer>> findTriplets(int[] arr, int target) {
List<List<Integer>> res = new ArrayList<>();
int n = arr.length;
// Generating all triplets
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
// If the sum of triplet is equal to target
// then add it's indices to the result
if (arr[i] + arr[j] + arr[k] == target) {
List<Integer> triplet = new ArrayList<>();
triplet.add(i);
triplet.add(j);
triplet.add(k);
res.add(triplet);
}
}
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {0, -1, 2, -3, 1};
int target = -2;
List<List<Integer>> ans = findTriplets(arr, target);
for (List<Integer> triplet : ans)
System.out.println(triplet.get(0) + " " +
triplet.get(1) + " " + triplet.get(2));
}
}
Python
# Python program to find all triplets having sum equal to
# target by exploring all possible triplets
def findTriplets(arr, target):
res = []
n = len(arr)
# Generating all triplets
for i in range(n - 2):
for j in range(i + 1, n - 1):
for k in range(j + 1, n):
# If the sum of triplet is equal to target
# then add it's indices to the result
if arr[i] + arr[j] + arr[k] == target:
res.append([i, j, k])
return res
arr = [0, -1, 2, -3, 1]
target = -2
ans = findTriplets(arr, target)
for triplet in ans:
print(triplet[0], triplet[1], triplet[2])
C#
// C# program to find all triplets having sum equal to
// target by exploring all possible triplets
using System;
using System.Collections.Generic;
class GfG {
static List<List<int>> FindTriplets(int[] arr, int target) {
List<List<int>> res = new List<List<int>>();
int n = arr.Length;
// Generating all triplets
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
// If the sum of triplet is equal to target
// then add it's indices to the result
if (arr[i] + arr[j] + arr[k] == target) {
res.Add(new List<int> { i, j, k });
}
}
}
}
return res;
}
public static void Main() {
int[] arr = { 0, -1, 2, -3, 1 };
int target = -2;
List<List<int>> ans = FindTriplets(arr, target);
foreach (var triplet in ans) {
Console.WriteLine($"{triplet[0]} {triplet[1]} {triplet[2]}");
}
}
}
JavaScript
// JavaScript program to find all triplets having sum equal to
// target by exploring all possible triplets
function findTriplets(arr, target) {
const res = [];
const n = arr.length;
// Generating all triplets
for (let i = 0; i < n - 2; i++) {
for (let j = i + 1; j < n - 1; j++) {
for (let k = j + 1; k < n; k++) {
// If the sum of triplet is equal to target
// then add it's indices to the result
if (arr[i] + arr[j] + arr[k] === target) {
res.push([i, j, k]);
}
}
}
}
return res;
}
const arr = [0, -1, 2, -3, 1];
const target = -2;
const ans = findTriplets(arr, target);
ans.forEach(triplet => {
console.log(triplet[0] + " " + triplet[1] + " " + triplet[2]);
});
[Expected Approach] Using Hashing – O(n^3) time and O(n^2) space
The idea is to store sum of all the pairs with their indices in the hash map or dictionary. Then, for each element in the array, we check if the pair which makes triplet's sum zero, exists in the hash map or not. Since there can be multiple valid pairs, we add each one to the hash set (to manage duplicates) while ensuring that all indices in the triplet are distinct.
In the worst case, this approach also has O(n^3) Time Complexity but in the average case, it is much faster than the Naive Approach as we are iterating over only those triplets whose sum is equal to target.
C++
// C++ program to find triplets having sum equal to
// target using hashing
#include <iostream>
#include <vector>
#include <set>
#include <unordered_map>
#include <algorithm>
using namespace std;
vector<vector<int>> findTriplets(vector<int> &arr, int target) {
// Ideally we should use an unordered_set here, but C++
// does not support vector as a key in an unordered_set
// So we have used set to keep the code simple. However
// set internally uses Red Black Tree and has O(Log n)
// time complexities for operations
set<vector<int>> resSet;
int n = arr.size();
unordered_map<int, vector<pair<int, int>>> mp;
// Store sum of all the pairs with their indices
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++)
mp[arr[i] + arr[j]].push_back({i, j});
}
for (int i = 0; i < n; i++) {
// Find remaining value to get sum equal to target
int rem = target - arr[i];
if (mp.find(rem) != mp.end()) {
vector<pair<int, int>> pairs = mp[rem];
for (auto p : pairs) {
// Ensure no two indices are same in triplet
if (p.first != i && p.second != i) {
vector<int> curr = {i, p.first, p.second};
sort(curr.begin(), curr.end());
resSet.insert(curr);
}
}
}
}
vector<vector<int>> res(resSet.begin(), resSet.end());
return res;
}
int main() {
vector<int> arr = {0, -1, 2, -3, 1};
int target = -2;
vector<vector<int>> ans = findTriplets(arr, target);
for (int i = 0; i < ans.size(); i++)
cout << ans[i][0] << " " << ans[i][1] << " " <<
ans[i][2] << endl;
return 0;
}
Java
// Java program to find triplets having sum equal to
// target using hashing
import java.util.*;
class GfG {
static List<List<Integer>> findTriplets(int[] arr, int target) {
// Set to handle duplicates
Set<List<Integer>> resSet = new HashSet<>();
int n = arr.length;
Map<Integer, List<int[]>> mp = new HashMap<>();
// Store sum of all the pairs with their indices
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
mp.computeIfAbsent(arr[i] + arr[j],
k -> new ArrayList<>()).add(new int[]{i, j});
}
}
for (int i = 0; i < n; i++) {
// Find remaining value to get sum equal to target
int rem = target - arr[i];
if (mp.containsKey(rem)) {
List<int[]> pairs = mp.get(rem);
for (int[] p : pairs) {
// Ensure no two indices are same in triplet
if (p[0] != i && p[1] != i) {
List<Integer> curr = Arrays.asList(i, p[0], p[1]);
Collections.sort(curr);
resSet.add(curr);
}
}
}
}
return new ArrayList<>(resSet);
}
public static void main(String[] args) {
int[] arr = {0, -1, 2, -3, 1};
int target = -2;
List<List<Integer>> ans = findTriplets(arr, target);
for (List<Integer> triplet : ans) {
System.out.println(triplet.get(0) + " " +
triplet.get(1) + " " + triplet.get(2));
}
}
}
Python
# Python program to find triplets having sum equal to
# target using hashing
def findTriplets(arr, target):
# Set to handle duplicates
resSet = set()
n = len(arr)
mp = {}
# Store sum of all the pairs with their indices
for i in range(n):
for j in range(i + 1, n):
s = arr[i] + arr[j]
if s not in mp:
mp[s] = []
mp[s].append((i, j))
for i in range(n):
# Find remaining value to get sum equal to target
rem = target - arr[i]
if rem in mp:
for p in mp[rem]:
# Ensure no two indices are the same in the triplet
if p[0] != i and p[1] != i:
curr = sorted([i, p[0], p[1]])
resSet.add(tuple(curr))
return [list(triplet) for triplet in resSet]
if __name__ == "__main__":
arr = [0, -1, 2, -3, 1]
target = -2
ans = findTriplets(arr, target)
for triplet in ans:
print(triplet[0], triplet[1], triplet[2])
C#
// C# program to find triplets having sum equal to
// target using hashing
using System;
using System.Collections.Generic;
using System.Linq;
class GfG {
static List<List<int> > FindTriplets(int[] arr,
int target) {
// Set to handle duplicates
HashSet<List<int> > resSet
= new HashSet<List<int> >(new ListComparer());
int n = arr.Length;
Dictionary<int, List<Tuple<int, int> > > mp
= new Dictionary<int,
List<Tuple<int, int> > >();
// Store sum of all the pairs with their indices
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int sum = arr[i] + arr[j];
if (!mp.ContainsKey(sum)) {
mp[sum] = new List<Tuple<int, int> >();
}
mp[sum].Add(new Tuple<int, int>(i, j));
}
}
for (int i = 0; i < n; i++) {
// Find remaining value to get sum equal to target
int rem = target - arr[i];
if (mp.ContainsKey(rem)) {
List<Tuple<int, int> > pairs = mp[rem];
foreach(var p in pairs)
{
// Ensure no two indices are the same in
// the triplet
if (p.Item1 != i && p.Item2 != i) {
List<int> curr
= new List<int>{ i, p.Item1,
p.Item2 };
curr.Sort();
resSet.Add(curr);
}
}
}
}
return new List<List<int> >(resSet);
}
static void Main() {
int[] arr = { 0, -1, 2, -3, 1 };
int target = -2;
List<List<int> > ans = FindTriplets(arr, target);
foreach(var triplet in ans)
Console.WriteLine($"{triplet[0]} {triplet[1]} {triplet[2]}");
}
class ListComparer : IEqualityComparer<List<int> > {
public bool Equals(List<int> x, List<int> y) {
return x.SequenceEqual<int>(y);
}
public int GetHashCode(List<int> obj) {
return string.Join(",", obj).GetHashCode();
}
}
}
JavaScript
// JavaScript program to find triplets having sum equal to
// target using hashing
function findTriplets(arr, target) {
// Set to handle duplicates
let resSet = new Set();
let n = arr.length;
let mp = new Map();
// Store sum of all the pairs with their indices
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
let sum = arr[i] + arr[j];
if (!mp.has(sum)) {
mp.set(sum, []);
}
mp.get(sum).push([i, j]);
}
}
for (let i = 0; i < n; i++) {
// Find remaining value to get sum equal to target
let rem = target - arr[i];
if (mp.has(rem)) {
let pairs = mp.get(rem);
for (let p of pairs) {
// Ensure no two indices are the same in the triplet
if (p[0] != i && p[1] != i) {
let curr = [i, p[0], p[1]].sort((a, b) => a - b);
resSet.add(curr.join(","));
}
}
}
}
return Array.from(resSet).map(triplet => triplet.split(",").map(Number));
}
const arr = [0, -1, 2, -3, 1];
const target = -2;
const ans = findTriplets(arr, target);
ans.forEach(triplet => {
console.log(`${triplet[0]} ${triplet[1]} ${triplet[2]}`);
});
Similar Reads
3 Sum - Count all triplets with given sum Given an array arr[] and a target value, the task is to find the count of triplets present in the given array having sum equal to the given target. Examples:Input: arr[] = [0, -1, 2, -3, 1], target = -2Output: 2Explanation: Two triplets that add up to -2 are:arr[0] + arr[3] + arr[4] = 0 + (-3) + (1)
10 min read
3 Sum - Find All Triplets with Zero Sum Given an array arr[], the task is to find all possible indices {i, j, k} of triplet {arr[i], arr[j], arr[k]} such that their sum is equal to zero and all indices in a triplet should be distinct (i != j, j != k, k != i). We need to return indices of a triplet in sorted order, i.e., i < j < k.Ex
11 min read
3 Sum â All Distinct Triplets with given Sum in an Array Given an array arr[], and an integer target, find all possible unique triplets in the array whose sum is equal to the given target value. We can return triplets in any order, but all the returned triplets should be internally sorted, i.e., for any triplet [q1, q2, q3], the condition q1 ⤠q2 ⤠q3 sho
15+ min read
Find triplet with minimum sum Given an array of distinct integers arr[]. The task is to find a triplet(a group of 3 elements) that has the minimum sum.Note: The size of the array is always greater than two.Examples: Input : arr[] = {1, 2, 3, 4, -1, 5, -2} Output : -2 1 - 1 - 2 = -2 Input : arr[] = {5, 6, 0, 0, 1} Output : 1 0 +
10 min read
Find Pythagorean Triplet with given sum Given a positive integer target, the task is to find all Pythagorean Triplets whose sum of the elements is equal to the given target. A triplet {a, b, c} is considered a Pythagorean triplet if it satisfies the condition a2 + b2 = c2.Examples : Input: target = 60Output: {{10, 24, 26}, {15, 20, 25}}Ex
11 min read