3 Sum – Find All Triplets with Zero Sum
Last Updated :
09 Oct, 2024
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.
Examples :
Input: arr[] = {0, -1, 2, -3, 1}
Output: {{0, 1, 4}, {2, 3, 4}}
Explanation: Two triplets with sum 0 are:
arr[0] + arr[1] + arr[4] = 0 + (-1) + 1 = 0
arr[2] + arr[3] + arr[4] = 2 + (-3) + 1 = 0
Input: arr[] = {1, -2, 1, 0, 5}
Output: {{0, 1, 2}}
Explanation: Only triplet which satisfies the condition is arr[0] + arr[1] + arr[2] = 1 + (-2) + 1 = 0
Input: arr[] = {2, 3, 1, 0, 5}
Output: {{}}
Explanation: There is no triplet with sum 0
[Naive Approach] Using Three Nested Loops – O(n^3) Time and O(1) Space
The simplest approach is to generate all possible triplets using three nested loops and if the sum of any triplet is equal to zero then add it to the result.
C++
// C++ program to find triplet having sum zero using
// three nested loops
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> findTriplets(vector<int> &arr) {
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 equals to zero
// then add it's indices to the result
if (arr[i] + arr[j] + arr[k] == 0)
res.push_back({i, j, k});
}
}
}
return res;
}
int main() {
vector<int> arr = {0, -1, 2, -3, 1};
vector<vector<int>> res = findTriplets(arr);
for(int i = 0; i < res.size(); i++)
cout << res[i][0] << " " << res[i][1] << " " << res[i][2] << endl;
return 0;
}
C
// C program to find triplet having sum zero using
// three nested loops
#include <stdio.h>
#include <stdlib.h>
#define MAX_LIMIT 100
void findTriplets(int arr[], int n, int res[][3], int* count) {
*count = 0;
// 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 equals zero
// then add it's indexes to reuslt
if (arr[i] + arr[j] + arr[k] == 0) {
res[*count][0] = i;
res[*count][1] = j;
res[*count][2] = k;
(*count)++;
}
}
}
}
}
int main() {
int arr[] = {0, -1, 2, -3, 1};
int n = sizeof(arr) / sizeof(arr[0]);
// res array to store all triplets
int res[MAX_LIMIT][3];
// Variable to store number of triplets found
int count = 0;
findTriplets(arr, n, res, &count);
for (int i = 0; i < count; i++)
printf("%d %d %d\n", res[i][0], res[i][1], res[i][2]);
return 0;
}
Java
// Java program to find triplet having sum zero using
// three nested loops
import java.util.ArrayList;
import java.util.List;
class GfG {
static ArrayList<ArrayList<Integer>> findTriplets(int[] arr) {
ArrayList<ArrayList<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 equals to zero
// then add it's indexes to the result
if (arr[i] + arr[j] + arr[k] == 0) {
ArrayList<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};
ArrayList<ArrayList<Integer>> res = findTriplets(arr);
for (List<Integer> triplet : res)
System.out.println(triplet.get(0) + " " + triplet.get(1)
+ " " + triplet.get(2));
}
}
Python
# Python program to find triplet with sum zero
# using three nested loops
def findTriplets(arr):
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 equals to zero
# then add it's indexes to the result
if arr[i] + arr[j] + arr[k] == 0:
res.append([i, j, k])
return res
arr = [0, -1, 2, -3, 1]
res = findTriplets(arr)
for triplet in res:
print(triplet[0], triplet[1], triplet[2])
C#
// C# program to find triplet with sum zero using
// three nested loops
using System;
using System.Collections.Generic;
class GfG {
static List<List<int>> FindTriplets(int[] arr) {
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 equals to zero
// then add it's indexes to the result
if (arr[i] + arr[j] + arr[k] == 0) {
res.Add(new List<int> { i, j, k });
}
}
}
}
return res;
}
public static void Main() {
int[] arr = { 0, -1, 2, -3, 1 };
List<List<int>> res = FindTriplets(arr);
foreach (var triplet in res) {
Console.WriteLine($"{triplet[0]} {triplet[1]} {triplet[2]}");
}
}
}
JavaScript
// JavaScript program to find triplet with sum zero
// using three nested loops
function findTriplets(arr) {
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 equals to zero
// then add it's indexes to the result
if (arr[i] + arr[j] + arr[k] === 0) {
res.push([i, j, k]);
}
}
}
}
return res;
}
const arr = [0, -1, 2, -3, 1];
const res = findTriplets(arr);
res.forEach(triplet => {
console.log(triplet[0] + " " + triplet[1] + " " + triplet[2]);
});
Time Complexity: O(n3), As three nested loops are used.
Auxiliary Space: O(1)
[Expected Approach] Using Hashing – O(n^2) Time and O(n^2) Space
The idea is to store sum of all the pairs with their indices the hash map. 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.
C++
// C++ program to find all triplets with zero sum using hashing
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> findTriplets(vector<int> &arr) {
// Set to handle duplicates
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 zero sum
int rem = -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};
vector<vector<int>> res = findTriplets(arr);
for (int i = 0; i < res.size(); i++)
cout << res[i][0] << " " << res[i][1] << " " << res[i][2] << endl;
return 0;
}
Java
// Java program to find all triplets with zero sum using hashing
import java.util.*;
class GfG {
static ArrayList<ArrayList<Integer>> findTriplets(int[] arr) {
// Set to handle duplicates
Set<ArrayList<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 zero sum
int rem = -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) {
ArrayList<Integer> curr =
new ArrayList<>(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};
ArrayList<ArrayList<Integer>> res = findTriplets(arr);
for (ArrayList<Integer> triplet : res) {
System.out.println(triplet.get(0) + " " +
triplet.get(1) + " " + triplet.get(2));
}
}
}
Python
# Python program to find all triplets with zero sum using hashing
def findTriplets(arr):
# 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 zero sum
rem = -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]
res = findTriplets(arr)
for triplet in res:
print(triplet[0], triplet[1], triplet[2])
C#
// C# program to find all triplets with zero sum using hashing
using System;
using System.Collections.Generic;
using System.Linq;
class GfG {
public static List<List<int>> FindTriplets(int[] arr) {
// 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++) {
int rem = -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 };
List<List<int>> res = FindTriplets(arr);
foreach (var triplet in res)
Console.WriteLine($"{triplet[0]} {triplet[1]} {triplet[2]}");
}
public 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 all triplets with zero sum using hashing
function findTriplets(arr) {
// 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 zero sum
let rem = -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 ans = findTriplets(arr);
ans.forEach(triplet => {
console.log(`${triplet[0]} ${triplet[1]} ${triplet[2]}`);
});
Time Complexity: O(n2), Since two nested loops are used.
Auxiliary Space: O(n2), Since a HashMap is used to store all the pairs.
Please refer 3Sum – Complete Tutorial for all list of problems on triplets in an array.