3 Sum - Find all Triplets with Given Sum

Last Updated : 8 Aug, 2026

Given an array arr[], and an integer target, find all possible 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 should hold.

Examples:

Input: arr[] = {0, -1, 2, -3, 1}, target = -2
Output: {{0, -3, 1}, {-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.

Input: arr[] = {1, 1, 1, 1}, target = 3
Output: {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}
Explanation: Four triples that add up to 3 are:
arr[0] + arr[1] + arr[2] = 1 + 1 + 1 = 3
arr[0] + arr[1] + arr[3] = 1 + 1 + 1 = 3
arr[0] + arr[2] + arr[3] = 1 + 1 + 1 = 3
arr[1] + arr[2] + arr[3] = 1 + 1 + 1 = 3

Try It Yourself
redirect icon

[Naive Approach] Explore all Triplets - O(n3) 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++
#include <iostream>
#include <vector>
#include <algorithm> 
using namespace std;

vector<vector<int>> threeSum(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 Sum is equal to target add it to result
                if (arr[i] + arr[j] + arr[k] == target){
                    vector<int> a = {arr[i], arr[j], arr[k]};
                    sort(a.begin(), a.end());
                    res.push_back(a);
                }
                    
            }
        }
    }
    return res;
}

int main() {
    vector<int> arr = {0, -1, 2, -3, 1};
    int target = -2;

    vector<vector<int>> ans = threeSum(arr, target);
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << endl;

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.Arrays;

class GfG {
    static List<List<Integer>> threeSum(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 to the result
                    if (arr[i] + arr[j] + arr[k] == target) {
                        List<Integer> a = Arrays.asList(arr[i], arr[j], arr[k]);
                        Collections.sort(a);
                        res.add(a);
                    }
                }
            }
        }
        return res;
    }

    public static void main(String[] args) {
      	int[] arr = {0, -1, 2, -3, 1};
	    int target = -2;

        List<List<Integer>> ans = threeSum(arr, target);
        for (List<Integer> triplet : ans) 
            System.out.println(triplet.get(0) + " " + 
                         triplet.get(1) + " " + triplet.get(2));
    }
}
Python
def threeSum(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 to the result
                if arr[i] + arr[j] + arr[k] == target:
                    a = sorted([arr[i], arr[j], arr[k]])
                    res.append(a)
    return res

arr = [0, -1, 2, -3, 1]
target = -2
ans = threeSum(arr, target)
for triplet in ans:
    print(triplet[0], triplet[1], triplet[2])
C#
using System;
using System.Collections.Generic;

class GfG {
    static List<List<int>> threeSum(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 to the result
                    if (arr[i] + arr[j] + arr[k] == target) {
                        List<int> a = new List<int> { arr[i], arr[j], arr[k] };
                        a.Sort();
                        res.Add(a);
                    }
                }
            }
        }
        return res;
    }

    public static void Main() {
      	int[] arr = { 0, -1, 2, -3, 1 };	
      	int target = -2;	

        List<List<int>> ans = threeSum(arr, target);
        foreach (var triplet in ans) {
            Console.WriteLine($"{triplet[0]} {triplet[1]} {triplet[2]}");
        }
    }
}
JavaScript
function threeSum(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) {
                    const a = [ arr[i], arr[j], arr[k] ].sort((x, y) => x - y);
                    res.push(a);
                }
            }
        }
    }
    return res;
}

// Driver Code

const arr = [0, -1, 2, -3, 1];
const target = -2;
const ans = threeSum(arr, target);
ans.forEach(triplet => {
    console.log(triplet[0] + " " + triplet[1] + " " + triplet[2]);
});

Output
-3 0 1
-3 -1 2

[Better Approach] Using Hashing – O(n3) time and O(n) space

Fix one number and use a hashmap while scanning the rest of the array to instantly check if the required third number has already appeared.

In the worst case, this approach also has O(n3) 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.

  • Create an empty hashmap to store the frequency of numbers seen so far.
  • Fix the first element of the triplet using index i, and reset the hashmap for every new i.
  • Traverse the array from i + 1 using index j, treating arr[j] as the second element of the triplet.
  • At each j, calculate the third number needed: numberNeeded = target - arr[i] - arr[j].
  • Check whether numberNeeded exists in the hashmap. If it does, it means a valid triplet can be formed — add one triplet to the result for every occurrence of numberNeeded recorded so far (this naturally handles duplicates).
  • After checking, insert/update arr[j] in the hashmap so future indices can use it as the "needed" number.
  • Repeat for all i and j, and return the collected triplets.

Consider the array: arr[] = [0, -1, -1, 1, 2], target = 0

We fix each i one at a time and use a hashmap to track how many times each number has been seen between i+1 and j-1.

i = 0 (arr[i] = 0)

  • Hash = { }
  • j = 1, arr[j] = -1: numberNeeded = 1. Not in hash. Insert -1. Hash = {-1: 1}
  • j = 2, arr[j] = -1: numberNeeded = 1. Not in hash. Insert -1. Hash = {-1: 2}
  • j = 3, arr[j] = 1: numberNeeded = -1. Found in hash (count 2) → triplets {0, 1, -1} and {0, 1, -1} added. Insert 1. Hash = {-1: 2, 1: 1}
  • j = 4, arr[j] = 2: numberNeeded = -2. Not in hash. Insert 2. Hash = {-1: 2, 1: 1, 2: 1}

Hashmap advantage at j = 3: count of -1 fetched directly in O(1), instead of scanning backward to count it manually.

i = 1 (arr[i] = -1)

  • Hash = { }
  • j = 2, arr[j] = -1: numberNeeded = 2. Not in hash. Insert -1. Hash = {-1: 1}
  • j = 3, arr[j] = 1: numberNeeded = 0. Not in hash. Insert 1. Hash = {-1: 1, 1: 1}
  • j = 4, arr[j] = 2: numberNeeded = -1. Found in hash (count 1) → triplet {-1, 2, -1} added. Insert 2. Hash = {-1: 1, 1: 1, 2: 1}

i = 2 (arr[i] = -1)

  • Hash = { }
  • j = 3, arr[j] = 1: numberNeeded = 0. Not in hash. Insert 1. Hash = {1: 1}
  • j = 4, arr[j] = 2: numberNeeded = -1. Not in hash. Insert 2. Hash = {1: 1, 2: 1}

No more valid i remain (only 2 elements left).

Final result: [[-1, 0, 1], [-1, 0, 1], [-1, -1, 2]]

C++
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;

vector<vector<int>> threeSum(vector<int>& arr, int target) {
    vector<vector<int>> result;
    int n = arr.size();

    // Fix the first element of the triplet using index i
    for (int i = 0; i < n - 2; i++) {

        // Stores frequency of each number seen so far between i+1 and j-1
        unordered_map<int, int> freqMap;

        // j scans forward, acting as the second element of the triplet
        for (int j = i + 1; j < n; j++) {

            // The third number needed to complete the sum with arr[i] and arr[j]
            int numberNeeded = target - arr[i] - arr[j];

            // Check if this needed number was already seen earlier
            if (freqMap.find(numberNeeded) != freqMap.end()) {

                // It may have occurred multiple times, so count all its occurrences
                int freqOfNumberNeeded = freqMap[numberNeeded];

                // Add one triplet for each past occurrence of the needed number
                for (int k = 0; k < freqOfNumberNeeded; k++) {

                    // Form the triplet from arr[i], arr[j], and the needed number
                    vector<int> triplet = {arr[i], arr[j], numberNeeded};

                    // Sort the 3 elements so the triplet has a consistent order
                    sort(triplet.begin(), triplet.end());

                    // Add this triplet to the result
                    result.push_back(triplet);
                }
            }

            // Update the frequency map with the current arr[j]
            freqMap[arr[j]]++;
        }
    }

    return result;
}

int main() {
    vector<int> arr = {0, -1, 2, -3, 1};
    int target = -2;

    vector<vector<int>> ans = threeSum(arr, target);
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << endl;

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import java.util.Collections;

class GfG {
    static List<List<Integer>> threeSum(int[] arr, int target) {
        List<List<Integer>> result = new ArrayList<>();
        int n = arr.length;

        // Fix the first element of the triplet using index i
        for (int i = 0; i < n - 2; i++) {

            // Stores frequency of each number seen so far between i+1 and j-1
            Map<Integer, Integer> freqMap = new HashMap<>();

            // j scans forward, acting as the second element of the triplet
            for (int j = i + 1; j < n; j++) {

                // The third number needed to complete the sum with arr[i] and arr[j]
                int numberNeeded = target - arr[i] - arr[j];

                // Check if this needed number was already seen earlier
                if (freqMap.containsKey(numberNeeded)) {

                    // It may have occurred multiple times, so count all its occurrences
                    int freqOfNumberNeeded = freqMap.get(numberNeeded);

                    // Add one triplet for each past occurrence of the needed number
                    for (int k = 0; k < freqOfNumberNeeded; k++) {

                        // Form the triplet from arr[i], arr[j], and the needed number
                        List<Integer> triplet = Arrays.asList(arr[i], arr[j], numberNeeded);

                        // Sort the 3 elements so the triplet has a consistent order
                        Collections.sort(triplet);

                        // Add this triplet to the result
                        result.add(triplet);
                    }
                }

                // Update the frequency map with the current arr[j]
                freqMap.put(
                    arr[j],
                    freqMap.getOrDefault(arr[j], 0) + 1
                );
            }
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {0, -1, 2, -3, 1};
        int target = -2;

        List<List<Integer>> ans = threeSum(arr, target);
        for (List<Integer> triplet : ans)
            System.out.println(triplet.get(0) + " " +
                                triplet.get(1) + " " + triplet.get(2));
    }
}
Python
def threeSum(arr, target):
    result = []
    n = len(arr)

    # Fix the first element of the triplet using index i
    for i in range(n - 2):

        # Stores frequency of each number seen so far between i+1 and j-1
        freq_map = {}

        # j scans forward, acting as the second element of the triplet
        for j in range(i + 1, n):

            # The third number needed to complete the sum with arr[i] and arr[j]
            number_needed = target - arr[i] - arr[j]

            # Check if this needed number was already seen earlier
            if number_needed in freq_map:

                # It may have occurred multiple times, so count all its occurrences
                freq_of_number_needed = freq_map[number_needed]

                # Add one triplet for each past occurrence of the needed number
                for k in range(freq_of_number_needed):

                    # Form the triplet from arr[i], arr[j], and the needed number
                    triplet = [arr[i], arr[j], number_needed]

                    # Sort the 3 elements so the triplet has a consistent order
                    triplet.sort()

                    # Add this triplet to the result
                    result.append(triplet)

            # Update the frequency map with the current arr[j]
            freq_map[arr[j]] = freq_map.get(arr[j], 0) + 1

    return result


if __name__ == "__main__":
    arr = [0, -1, 2, -3, 1]
    target = -2
    print(threeSum(arr, target))
JavaScript
function threeSum(arr, target) {
    const result = [];
    const n = arr.length;

    // Fix the first element of the triplet using index i
    for (let i = 0; i < n - 2; i++) {

        // Stores frequency of each number seen so far between i+1 and j-1
        const freqMap = new Map();

        // j scans forward, acting as the second element of the triplet
        for (let j = i + 1; j < n; j++) {

            // The third number needed to complete the sum with arr[i] and arr[j]
            const numberNeeded = target - arr[i] - arr[j];

            // Check if this needed number was already seen earlier
            if (freqMap.has(numberNeeded)) {

                // It may have occurred multiple times, so count all its occurrences
                const freqOfNumberNeeded = freqMap.get(numberNeeded);

                // Add one triplet for each past occurrence of the needed number
                for (let k = 0; k < freqOfNumberNeeded; k++) {

                    // Form the triplet from arr[i], arr[j], and the needed number
                    const triplet = [arr[i], arr[j], numberNeeded];

                    // Sort the 3 elements so the triplet has a consistent order
                    triplet.sort((a, b) => a - b);

                    // Add this triplet to the result
                    result.push(triplet);
                }
            }

            // Update the frequency map with the current arr[j]
            freqMap.set(arr[j], (freqMap.get(arr[j]) || 0) + 1);
        }
    }

    return result;
}

// Driver Code
const arr = [0, -1, 2, -3, 1];
const target = -2;
const ans = threeSum(arr, target);
ans.forEach(triplet => {
    console.log(triplet[0] + " " + triplet[1] + " " + triplet[2]);
});

Output
-3 0 1
-3 -1 2


Comment