2 Sum - Find All Pairs With Given Sum

Last Updated : 19 Aug, 2026

Given an array arr[] and a target value, the task is to find all possible indices (i, j) of pairs (arr[i], arr[j]) whose sum is equal to target and i != j. We can return pairs in any order, but all the returned pairs should be internally sorted, that is for any pair(i, j), i should be less than j.

Examples:

Input: arr[] = {10, 20, 30, 20, 10, 30}, target = 50
Output: {{1, 2}, {1, 5}, {2, 3}, {3, 5}}
Explanation: All pairs with sum = 50 are:

  • arr[1] + arr[2] = 20 + 30 = 50
  • arr[1] + arr[5] = 20 + 30 = 50
  • arr[2] + arr[3] = 30 + 20 = 50
  • arr[3] + arr[5] = 20 + 30 = 50

Input: arr[] = {10, 20, 30, 20, 10, 30}, target = 80
Output: { }
Explanation: No pairs have sum = 80.

Try It Yourself
redirect icon

[Naive Approach] Using Nested Loops - O(n^2) Time and O(1) Space

The simplest approach is to generate all possible pairs from the given array arr[] and if the sum of elements of the pairs is equal to target, then add it to the result.

C++
// C++ Code to find all pairs using nested loops

#include <iostream>
#include <vector>
using namespace std;

// function to find all pairs 
vector<vector<int>> findAllPairs(vector<int> &arr, int target) {
	int n = arr.size();
  	vector<vector<int>> res;
  
    // Two nested loops to generate all pairs
    for(int i = 0; i < n; i++) {
    	for(int j = i + 1; j < n; j++) {
          
            // If sum of pair equals target, add it to result
          	if(arr[i] + arr[j] == target) {
            	res.push_back({i, j});
            }
        }
    }
    return res;
}

int main() {

    vector<int> arr = {10, 20, 30, 20, 10, 30};
    int target = 50;
  
    vector<vector<int>> res = findAllPairs(arr, target);
    for(auto pair: res) {
    	cout << pair[0] << " " << pair[1] << "\n";
    }
    return 0;
}
C
// C Code to find all pairs using nested loops

#include <stdio.h>

// function to find all pairs 
void findAllPairs(int *arr, int n, int target) {
  
    // Two nested loops to generate all pairs
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
          
            // If sum of pair equals target, print it
            if (arr[i] + arr[j] == target) {
                printf("%d %d\n", i, j);
            }
        }
    }
}

int main() {
    int arr[] = {10, 20, 30, 20, 10, 30};
    int target = 50;
    int n = sizeof(arr) / sizeof(arr[0]);

    findAllPairs(arr, n, target);

    return 0;
}
Java
// Java Code to find all pairs using nested loops

import java.util.ArrayList;
import java.util.List;

class GfG {

    // function to find all pairs 
    static List<List<Integer>> findAllPairs(int[] arr, int target) {
        int n = arr.length;
        List<List<Integer>> res = new ArrayList<>();
  
        // Two nested loops to generate all pairs
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
              
                // If sum of pair equals target, add it to result
                if(arr[i] + arr[j] == target) {
                    List<Integer> pair = new ArrayList<>();
                    pair.add(i);
                    pair.add(j);
                    res.add(pair);
                }
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {10, 20, 30, 20, 10, 30};
        int target = 50;
  
        List<List<Integer>> res = findAllPairs(arr, target);
        for(List<Integer> pair: res) {
            System.out.println(pair.get(0) + " " + pair.get(1));
        }
    }
}
Python
# Python Code to find all pairs using nested loops

def findAllPairs(arr, target):
    n = len(arr)
    res = []
  
    # Two nested loops to generate all pairs
    for i in range(n):
        for j in range(i + 1, n):
            # If sum of pair equals target, add it to result
            if arr[i] + arr[j] == target:
                res.append([i, j])
    return res

if __name__ == "__main__":
    arr = [10, 20, 30, 20, 10, 30]
    target = 50
  
    res = findAllPairs(arr, target)
    for pair in res:
        print(pair[0], pair[1])
C#
// C# Code to find all pairs using nested loops

using System;
using System.Collections.Generic;

class GfG {
  
    // function to find all pairs 
    static List<List<int>> findAllPairs(List<int> arr, int target) {
        int n = arr.Count;
        List<List<int>> res = new List<List<int>>();

        // Two nested loops to generate all pairs
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
              
                // If sum of pair equals target, add it to result
                if (arr[i] + arr[j] == target) {
                    res.Add(new List<int> { i, j });
                }
            }
        }
        return res;
    }

    static void Main(string[] args) {
        List<int> arr = new List<int> { 10, 20, 30, 20, 10, 30 };
        int target = 50;

        List<List<int>> res = findAllPairs(arr, target);
        foreach (var pair in res) {
            Console.WriteLine(pair[0] + " " + pair[1]);
        }
    }
}
JavaScript
// JavaScript Code to find all pairs using nested loops

// function to find all pairs 
function findAllPairs(arr, target) {
    let n = arr.length;
    let res = [];
  
    // Two nested loops to generate all pairs
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
          
            // If sum of pair equals target, add it to result
            if (arr[i] + arr[j] === target) {
                res.push([i, j]);
            }
        }
    }
    return res;
}

const arr = [10, 20, 30, 20, 10, 30];
const target = 50;

const res = findAllPairs(arr, target);
for (const pair of res) {
    console.log(pair[0] + " " + pair[1]);
}

Output
1 2
1 5
2 3
3 5

[Expected Approach] Using Hashing - O(n^2) Time and O(n) Space

The idea is to maintain a hash map with element as key and its indices as values. Iterate over the array and for each element arr[i], if (target - arr[i]) exists in the hash map, then pair i with all indices of (target - arr[i]) and store them in result.

In the worst case, this approach also takes O(n^2) time but in the average case, it is much faster than Naive approach as we are iterating over only those pairs whose sum is equal to target.

C++
// C++ Code to find all pairs using hashing

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

// function to find all pairs
vector<vector<int>> findAllPairs(vector<int> &arr, int target)
{
    int n = arr.size();

    // buckets[i] stores all j (j > i) such that 
    // arr[i] + arr[j] = target
    // filled in increasing order of j automatically, 
    // since we scan left to right
    vector<vector<int>> buckets(n);

    // maps a value to the list of indices where 
    // it has occurred so far
    unordered_map<int, vector<int>> mp;
    mp.reserve(n);

    for (int i = 0; i < n; i++)
    {
        int need = target - arr[i];

        // if a smaller index with the complementary 
        // value exists, pair it with i
        if (mp.find(need) != mp.end())
        {
            for (int idx : mp[need])
                buckets[idx].push_back(i);
        }

        mp[arr[i]].push_back(i);
    }

    // flatten buckets in order 0..n-1; result is 
    // already lexicographically sorted, since bucket 
    // index is the first element and each bucket's
    // contents are appended in increasing order of 
    // the second element
    vector<vector<int>> res;
    for (int i = 0; i < n; i++)
    {
        for (int j : buckets[i])
            res.push_back({i, j});
    }

    return res;
}

int main()
{

    vector<int> arr = {10, 20, 30, 20, 10, 30};
    int target = 50;

    vector<vector<int>> res = findAllPairs(arr, target);
    for (auto pair : res)
    {
        cout << pair[0] << " " << pair[1] << "\n";
    }
    return 0;
}
Java
import java.util.*;

class Main {
    public static List<List<Integer>> findAllPairs(int[] arr, int target) {
        int n = arr.length;

        // buckets[i] stores all j (j > i) such that 
        // arr[i] + arr[j] = target
        // filled in increasing order of j automatically, 
        // since we scan left to right
        List<List<List<Integer>>> buckets = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            buckets.add(new ArrayList<>());
        }

        // maps a value to the list of indices where 
        // it has occurred so far
        Map<Integer, List<Integer>> mp = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int need = target - arr[i];

            // if a smaller index with the complementary 
            // value exists, pair it with i
            if (mp.containsKey(need)) {
                for (int idx : mp.get(need)) {
                    buckets.get(idx).add(Arrays.asList(idx, i));
                }
            }

            if (!mp.containsKey(arr[i])) {
                mp.put(arr[i], new ArrayList<>());
            }
            mp.get(arr[i]).add(i);
        }

        // flatten buckets in order 0..n-1; result is 
        // already lexicographically sorted, since bucket 
        // index is the first element and each bucket's
        // contents are appended in increasing order of 
        // the second element
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            for (List<Integer> pair : buckets.get(i)) {
                res.add(pair);
            }
        }

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {10, 20, 30, 20, 10, 30};
        int target = 50;

        List<List<Integer>> res = findAllPairs(arr, target);
        for (List<Integer> pair : res) {
            System.out.println(pair.get(0) + " " + pair.get(1));
        }
    }
}
Python
def findAllPairs(arr, target):
    n = len(arr)

    # buckets[i] stores all j (j > i) such that 
    # arr[i] + arr[j] = target
    # filled in increasing order of j automatically, 
    # since we scan left to right
    buckets = [[] for _ in range(n)]

    # maps a value to the list of indices where 
    # it has occurred so far
    mp = {}

    for i in range(n):
        need = target - arr[i]

        # if a smaller index with the complementary 
        # value exists, pair it with i
        if need in mp:
            for idx in mp[need]:
                buckets[idx].append((idx, i))

        if arr[i] not in mp:
            mp[arr[i]] = []
        mp[arr[i]].append(i)

    # flatten buckets in order 0..n-1; result is 
    # already lexicographically sorted, since bucket 
    # index is the first element and each bucket's
    # contents are appended in increasing order of 
    # the second element
    res = []
    for i in range(n):
        for pair in buckets[i]:
            res.append(pair)

    return res


if __name__ == '__main__':
    arr = [10, 20, 30, 20, 10, 30]
    target = 50

    res = findAllPairs(arr, target)
    for pair in res:
        print(pair[0], pair[1])
C#
using System;
using System.Collections.Generic;

class Program
{
    // function to find all pairs
    public static List<List<int>> findAllPairs(int[] arr, int target)
    {
        int n = arr.Length;

        // buckets[i] stores all j (j > i) such that 
        // arr[i] + arr[j] = target
        // filled in increasing order of j automatically, 
        // since we scan left to right
        List<List<int>> buckets = new List<List<int>>();
        for (int i = 0; i < n; i++) {
            buckets.Add(new List<int>(2));
        }

        // maps a value to the list of indices where 
        // it has occurred so far
        Dictionary<int, List<int>> mp = new Dictionary<int, List<int>>();

        for (int i = 0; i < n; i++)
        {
            int need = target - arr[i];

            // if a smaller index with the complementary 
            // value exists, pair it with i
            if (mp.ContainsKey(need))
            {
                foreach (int idx in mp[need])
                {
                    buckets[idx].Add(i);
                }
            }

            if (!mp.ContainsKey(arr[i]))
            {
                mp[arr[i]] = new List<int>();
            }
            mp[arr[i]].Add(i);
        }

        // flatten buckets in order 0..n-1; result is 
        // already lexicographically sorted, since bucket 
        // index is the first element and each bucket's
        // contents are appended in increasing order of 
        // the second element
        List<List<int>> res = new List<List<int>>();
        for (int i = 0; i < n; i++)
        {
            foreach (int pair in buckets[i])
            {
                res.Add(new List<int>{i, pair});
            }
        }

        return res;
    }

    static void Main(string[] args)
    {
        int[] arr = { 10, 20, 30, 20, 10, 30 };
        int target = 50;

        List<List<int>> res = findAllPairs(arr, target);
        foreach (var pair in res)
        {
            Console.WriteLine(pair[0] + " " + pair[1]);
        }
    }
}
JavaScript
function findAllPairs(arr, target) {
    const n = arr.length;

    // buckets[i] stores all j (j > i) such that 
    // arr[i] + arr[j] = target
    // filled in increasing order of j automatically, 
    // since we scan left to right
    const buckets = Array.from({ length: n }, () => []);

    // maps a value to the list of indices where 
    // it has occurred so far
    const mp = new Map();

    for (let i = 0; i < n; i++) {
        const need = target - arr[i];

        // if a smaller index with the complementary 
        // value exists, pair it with i
        if (mp.has(need)) {
            for (const idx of mp.get(need)) {
                buckets[idx].push([idx, i]);
            }
        }

        if (!mp.has(arr[i])) {
            mp.set(arr[i], []);
        }
        mp.get(arr[i]).push(i);
    }

    // flatten buckets in order 0..n-1; result is 
    // already lexicographically sorted, since bucket 
    // index is the first element and each bucket's
    // contents are appended in increasing order of 
    // the second element
    const res = [];
    for (let i = 0; i < n; i++) {
        for (const pair of buckets[i]) {
            res.push(pair);
        }
    }

    return res;
}

const arr = [10, 20, 30, 20, 10, 30];
const target = 50;

const res = findAllPairs(arr, target);
for (const pair of res) {
    console.log(pair[0] + ''+ pair[1]);
}

Output
1 2
2 3
1 5
3 5


Comment