Open In App

2 Sum – All distinct pairs with given sum

Last Updated : 01 Sep, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] and an integer target, We need to find all distinct pairs in the array such that their sum equals target.

Examples:

Input: arr[] = [1, 5, 7, -1, 5], target= 6
Output: [[1, 5], [-1, 7]]
Explanation: There are only two pairs that add up to 6: [1, 5]and [-1, 7].

Input: arr[] = [1, 9, -1, 8, 6], target = 4
Output: []
Explanation: No pairs add up to 4.

[Naive Approach] Using Two Nested Loops

A simple approach is to generate all possible pairs using two nested loops and if they add up to target value, then for each such pair check whether this pair already exists in the result or not.

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> distinctPairs(vector<int> &arr, int target) {
    vector<vector<int>> res;
    int n = arr.size();
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            
            if (arr[i] + arr[j] == target) {
                int first = min(arr[i], arr[j]);
                int second = max(arr[i], arr[j]);
                vector<int> cur = {first, second};
              	if(find(res.begin(), res.end(), cur) == res.end())
                	res.push_back(cur);
            }
        }
    }
    return res;
}
int main() {
    vector<int> arr = {1, 5, 7, -1, 5};
    int target = 6;
    vector<vector<int>> res = distinctPairs(arr, target);
    for (int i = 0; i < res.size(); i++)
        cout << res[i][0] << " " << res[i][1] << endl;
    return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void distinctPairs(int arr[], int n, int target) {
    int res[1000][2];
    int res_count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (arr[i] + arr[j] == target) {
                int first = arr[i] < arr[j] ? arr[i] : arr[j];
                int second = arr[i] > arr[j] ? arr[i] : arr[j];
                bool isDistinct = true;
                for (int k = 0; k < res_count; k++) {
                    if (res[k][0] == first && res[k][1] == second) {
                        isDistinct = false;
                        break;
                    }
                }
                if (isDistinct) {
                    res[res_count][0] = first;
                    res[res_count][1] = second;
                    res_count++;
                }
            }
        }
    }

    for (int i = 0; i < res_count; i++) {
        printf("%d %d\n", res[i][0], res[i][1]);
    }
}
int main() {
    int arr[] = {1, 5, 7, -1, 5};
    int target = 6;
    int n = sizeof(arr) / sizeof(arr[0]);
    distinctPairs(arr, n, target);
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;

class GfG {
    static List<List<Integer>> distinctPairs(int[] arr, int target) {
        List<List<Integer>> res = new ArrayList<>();
        int n = arr.length;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[i] + arr[j] == target) {
                    int first = Math.min(arr[i], arr[j]);
                    int second = Math.max(arr[i], arr[j]);
                    List<Integer> cur = new ArrayList<>
                      					(Arrays.asList(first, second));
                    
                    if (!res.contains(cur))
                        res.add(cur);
                }
            }
        }
        return res;
    }
    public static void main(String[] args) {
        int[] arr = {1, 5, 7, -1, 5};
        int target = 6;
        List<List<Integer>> res = distinctPairs(arr, target);

        for (List<Integer> pair : res)
            System.out.println(pair.get(0) + " " + pair.get(1));
    }
}
Python
def distinctPairs(arr, target):
    res = []
    n = len(arr)
    # Iterating over all possible pairs
    for i in range(n):
        for j in range(i + 1, n):
            if arr[i] + arr[j] == target:
                cur = [min(arr[i], arr[j]), max(arr[i], arr[j])]

                if cur not in res:
                    res.append(cur)

    return res
if __name__ == "__main__":
    arr = [1, 5, 7, -1, 5]
    target = 6
    res = distinctPairs(arr, target)

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

class GfG {
    static List<List<int>> distinctPairs(int[] arr, int target) {
        List<List<int>> res = new List<List<int>>();
        int n = arr.Length;

        
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[i] + arr[j] == target) {
                    int first = Math.Min(arr[i], arr[j]);
                    int second = Math.Max(arr[i], arr[j]);
                    List<int> cur = new List<int> { first, second };
                  
                    if (!res.Exists(x => x[0] == cur[0] && x[1] == cur[1]))
                        res.Add(cur);
                }
            }
        }
        return res;
    }
    static void Main() {
        int[] arr = { 1, 5, 7, -1, 5 };
        int target = 6;
        List<List<int>> res = distinctPairs(arr, target);

        foreach (var pair in res)
            Console.WriteLine($"{pair[0]} {pair[1]}");
    }
}
JavaScript
function distinctPairs(arr, target) {
    let res = [];
    let n = arr.length;
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            if (arr[i] + arr[j] === target) {
                let first = Math.min(arr[i], arr[j]);
                let second = Math.max(arr[i], arr[j]);
                let cur = [first, second];
                if (!res.some(pair => pair[0] === cur[0] && pair[1] === cur[1])) {
                    res.push(cur);
                }
            }
        }
    }

    return res;
}
let arr = [1, 5, 7, -1, 5];
let target = 6;
let res = distinctPairs(arr, target);

for (let i = 0; i < res.length; i++) 
    console.log(res[i][0] + " " + res[i][1]);

Output
1 5
-1 7

Time Complexity: O(n^3), two nested loops generate all pairs (O(n²)), and for each pair, find() scans the result vector in O(n).
Auxiliary Space: O(1),

[Better Approach 1] Using Hash Set - O(n^2* log n) Time and O(n) Space

A better approach is to generate all possible pairs using two nested loops, check if their sum equals the target, and store them in a hash set to automatically eliminate duplicate pairs.

C++
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> distinctPairs(vector<int> &arr, int target) {
    vector<vector<int>> res;
    int n = arr.size();
    set<vector<int>> st;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (arr[i] + arr[j] == target) {
                int first = min(arr[i], arr[j]);
                int second = max(arr[i], arr[j]);
              	vector<int> cur = {first, second};
              	// If the pair is not already in the set, add it
                if (st.find(cur) == st.end()) {
                    res.push_back(cur); 
                    st.insert(cur);    
                }
            }
        }
    }
  	return res;
}
int main() {
    vector<int> arr = {1, 5, 7, -1, 5};
    int target = 6;
    vector<vector<int>> res = distinctPairs(arr, target);
    for (int i = 0; i < res.size(); i++)
        cout << res[i][0] << " " << res[i][1] << endl;
    return 0;
}
Java
import java.util.*;

class GfG {
  
    static List<List<Integer>> distinctPairs(int[] arr, int target) {
        List<List<Integer>> res = new ArrayList<>();
        int n = arr.length;
        // Set to handle duplicates using sorted pairs
        Set<List<Integer>> st = new HashSet<>();

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[i] + arr[j] == target) {
                    int first = Math.min(arr[i], arr[j]);
                    int second = Math.max(arr[i], arr[j]);
                    List<Integer> cur = new ArrayList<>
                      					(Arrays.asList(first, second));

                    if (!st.contains(cur)) {
                        res.add(cur);
                        st.add(cur);
                    }
                }
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 7, -1, 5};
        int target = 6;
        List<List<Integer>> res = distinctPairs(arr, target);

        for (List<Integer> pair : res) {
            System.out.println(pair.get(0) + " " + pair.get(1));
        }
    }
}
Python
def distinctPairs(arr, target):
    res = []
    n = len(arr)
    # Iterating over all possible pairs
    for i in range(n):
        for j in range(i + 1, n):
            if arr[i] + arr[j] == target:
                cur = [min(arr[i], arr[j]), max(arr[i], arr[j])]

                if cur not in res:
                    res.append(cur)

    return res
if __name__ == "__main__":
    arr = [1, 5, 7, -1, 5]
    target = 6
    res = distinctPairs(arr, target)

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

class GfG {
  
    static List<List<int>> distinctPairs(int[] arr, int target) {
        List<List<int>> res = new List<List<int>>();
        int n = arr.Length;

        // Set to handle duplicates using sorted pairs
        HashSet<(int, int)> st = new HashSet<(int, int)>();

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[i] + arr[j] == target) {
                    int first = Math.Min(arr[i], arr[j]);
                    int second = Math.Max(arr[i], arr[j]);

                    var cur = (first, second);
                    if (!st.Contains(cur)) {
                        res.Add(new List<int> { first, second });
                        st.Add(cur);
                    }
                }
            }
        }
        return res;
    }

    static void Main() {
        int[] arr = { 1, 5, 7, -1, 5 };
        int target = 6;
        List<List<int>> res = distinctPairs(arr, target);

        foreach (var pair in res) {
            Console.WriteLine(pair[0] + " " + pair[1]);
        }
    }
}
JavaScript
function distinctPairs(arr, target) {
    let res = [];
    let n = arr.length;

    // Set to handle duplicates using sorted pairs
    let st = new Set();

    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            if (arr[i] + arr[j] === target) {
                let first = Math.min(arr[i], arr[j]);
                let second = Math.max(arr[i], arr[j]);
                let cur = [first, second];

                let curString = cur.toString();
                if (!st.has(curString)) {
                    res.push(cur);
                    st.add(curString);
                }
            }
        }
    }
    return res;
}

let arr = [1, 5, 7, -1, 5];
let target = 6;
let res = distinctPairs(arr, target);

res.forEach(pair => console.log(pair[0], pair[1]));

Output
1 5
-1 7

Time Complexity: O(n² * log n).
Auxiliary Space: O(n), for hash set.

[Expected Approach 1] Using Two Pointers Technique – O(n*logn) Time and O(1) Space

The idea is to sort the array and use two pointers technique to find all the pairs. Initialize two pointers at the beginning and end of the array. Now, compare the sum of elements at these pointers:

  • If sum = target, store the pair and skip duplicates to ensure they are distinct.
  • If sum < target, we move the left pointer towards right.
  • If sum > target, we move the right pointer towards left.

This continues until all pairs are checked, giving us all the distinct pairs.

C++
#include <iostream
#include <vector>

using namespace std;
vector<vector<int>> distinctPairs(vector<int> &arr, int target) {
    vector<vector<int>> res;
    int n = arr.size();
  	sort(arr.begin(), arr.end());
    int left = 0;
    int right = n - 1;
    //iterate until pointers meet
    while (left < right) {
        //skip duplicates element on left side
        if (left > 0 && arr[left] == arr[left - 1]) {
            left++;
            continue;
        }
        // skip duplicate elements on right side
        if (right < n - 1 && arr[right] == arr[right + 1]) {
            right--;
            continue;
        }
         // if pair sum equals target, add to result
        if (arr[left] + arr[right] == target) {
            res.push_back({arr[left], arr[right]});
            left++;
            right--;
        }
         // if sum is greater than target, move right pointer left
        else if (arr[left] + arr[right] > target)
            right--;
            // if sum is smaller than target, move left pointer right
        else
            left++;
    }

    return res;
}

int main() {
    vector<int> arr = {1, 5, 7, -1, 5};
    int target = 6;

    vector<vector<int>> res = distinctPairs(arr, target);
    for (int i = 0; i < res.size(); i++)
        cout << res[i][0] << " " << res[i][1] << endl;
    return 0;
}
C
#include <stdio.h>
int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

void distinctPairs(int arr[], int n, int target) {
    qsort(arr, n, sizeof(int), compare);

    int left = 0;
    int right = n - 1;

    while (left < right) {
        
        if (left > 0 && arr[left] == arr[left - 1]) {
            left++;
            continue;
        }
        if (right < n - 1 && arr[right] == arr[right + 1]) {
            right--;
            continue;
        }

        // Check if sum equals the target
        if (arr[left] + arr[right] == target) {
            printf("%d %d\n", arr[left], arr[right]);
            left++;
            right--;
        }
        else if (arr[left] + arr[right] > target) {
            right--;
        }
        else {
            left++;
        }
    }
}

int main() {
    int arr[] = {1, 5, 7, -1, 5};
    int target = 6;
    int n = sizeof(arr) / sizeof(arr[0]);
    distinctPairs(arr, n, target);
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class GfG {
    static List<List<Integer>> distinctPairs(int[] arr, int target) {
        List<List<Integer>> res = new ArrayList<>();
		
        int l = 0;
        int r = arr.length - 1;

        while (l < r) {
          
            if (l > 0 && arr[l] == arr[l - 1]) {
                l++;
                continue;
            }

            if (r < arr.length - 1 && arr[r] == arr[r + 1]) {
                r--;
                continue;
            }
            if (arr[l] + arr[r] == target) {
                res.add(Arrays.asList(arr[l], arr[r]));
                l++;
                r--;
            } 
          	else if (arr[l] + arr[r] > target) {
                r--;
            } 
          	else {
                l++;
            }
        }

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 7, -1, 5};
        int target = 6;
		Arrays.sort(arr);
      
        List<List<Integer>> res = distinctPairs(arr, target);
        for (List<Integer> pair : res) {
            System.out.println(pair.get(0) + " " + pair.get(1));
        }
    }
}
Python
def distinctPairs(arr, target):
    res = []
    n = len(arr)

    arr.sort()

    left = 0
    right = n - 1

    while left < right:
        
     
        if left > 0 and arr[left] == arr[left - 1]:
            left += 1
            continue
        if right < n - 1 and arr[right] == arr[right + 1]:
            right -= 1
            continue

       
        if arr[left] + arr[right] == target:
            res.append([arr[left], arr[right]])
            left += 1
            right -= 1
        elif arr[left] + arr[right] > target:
            right -= 1
        else:
            left += 1

    return res

if __name__ == "__main__":
    arr = [1, 5, 7, -1, 5]
    target = 6

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

class GfG {
    static List<List<int>> DistinctPairs(int[] arr, int target) {
        List<List<int>> res = new List<List<int>>();
        int n = arr.Length;

        Array.Sort(arr);
  
        int left = 0;
        int right = n - 1;

        while (left < right) {
        
            if (left > 0 && arr[left] == arr[left - 1]) {
                left++;
                continue;
            }
            if (right < n - 1 && arr[right] == arr[right + 1]) {
                right--;
                continue;
            }

            if (arr[left] + arr[right] == target) {
                res.Add(new List<int> { arr[left], arr[right] });
                left++;
                right--;
            }
            else if (arr[left] + arr[right] > target)
                right--;
            else
                left++;
        }

        return res;
    }

    static void Main() {
        int[] arr = { 1, 5, 7, -1, 5 };
        int target = 6;

        List<List<int>> res = DistinctPairs(arr, target);
        foreach (var pair in res) {
            Console.WriteLine(pair[0] + " " + pair[1]);
        }
    }
}
JavaScript
function distinctPairs(arr, target) {
    let res = [];
    let n = arr.length;
  arr.sort((a, b) => a - b);
  
    let left = 0;
    let right = n - 1;

    while (left < right) {
    
        
        if (left > 0 && arr[left] === arr[left - 1]) {
            left++;
            continue;
        }
        if (right < n - 1 && arr[right] === arr[right + 1]) {
            right--;
            continue;
        }

        if (arr[left] + arr[right] === target) {
            res.push([arr[left], arr[right]]);
            left++;
            right--;
        } 
        else if (arr[left] + arr[right] > target)
            right--;
        else 
            left++;
    }

    return res;
}

const arr = [1, 5, 7, -1, 5];
const target = 6;

const res = distinctPairs(arr, target);
for (let i = 0; i < res.length; i++)
    console.log(res[i][0] + " " + res[i][1]);

Output
-1 7
1 5

Time Complexity: O(n*log(n)), for sorting the array
Auxiliary Space: O(1)

[Expected Approach 2] Using Hash Map – O(n) Time and O(n) Space

The idea is to maintain a hash map to track how many times each element has occurred in the array so far. Traverse all the elements and for each element arr[i], check if the complement (target – arr[i]) already exists in the map, if it exists then we have found a pair whose sum is equal to target.

To avoid including duplicate pairs, we handle two cases:

When arr[i] == complement:

  • We check if arr[i] has appeared exactly once before index i.
  • If it has, then arr[i] can pair with itself to form a valid pair with sum = target.
  • If it has appeared more than once, the pair has already been counted earlier, so this occurrence would create a duplicate and should be ignored.

When arr[i] != complement:

  • We check that the complement has appeared at least once before index i.
  • At the same time, arr[i] should not have appeared before index i.
  • If both conditions hold, then (arr[i], complement) forms a unique pair with sum = target.
C++
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

vector<vector<int>> distinctPairs(vector<int> &arr, int target) {
    vector<vector<int>> res;
    int n = arr.size();
    unordered_map<int, int> freq;

    for (int i = 0; i < n; i++) {
        int complement = target - arr[i];
        if (complement == arr[i]) {
            // If we have already seen this number exactly once before,
            // then this is the first valid duplicate pair (arr[i], arr[i])
            if (freq[complement] == 1) 
                res.push_back({arr[i], arr[i]});
        }
        //complement must exist before and current number should not be processed before
        else if (freq[complement] > 0 && freq[arr[i]] == 0) {
            res.push_back({min(arr[i], complement), max(arr[i], complement)});
        }

        freq[arr[i]]++;
    }
    return res;
}
int main() {
    vector<int> arr = {1, 5, 7, -1, 5};
    int target = 6;
    vector<vector<int>> res = distinctPairs(arr, target);
    for (vector<int> &pair : res)
        cout << pair[0] << " " << pair[1] << endl;

    return 0;
}
Java
import java.util.*;
class GfG {
    static List<List<Integer>> distinctPairs(int[] arr, int target) {
        List<List<Integer>> res = new ArrayList<>();
        int n = arr.length;

        Map<Integer, Integer> freq = new HashMap<>();

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


            if (complement == arr[i]) {
                if (freq.getOrDefault(complement, 0) == 1) 
                    res.add(Arrays.asList(arr[i], arr[i]));
            }
            
            // if complement is not equal to arr[i], then there should
            // be at least one occurrence of complement and no occurrence
            // of current element in the hash map
            else if (freq.getOrDefault(complement, 0) > 0 
                      			&& freq.getOrDefault(arr[i], 0) == 0) {
                int first = Math.min(arr[i], complement);
                int second = Math.max(arr[i], complement);
                res.add(Arrays.asList(first, second));
            }

            freq.put(arr[i], freq.getOrDefault(arr[i], 0) + 1);
        }

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 7, -1, 5};
        int target = 6;

        List<List<Integer>> res = distinctPairs(arr, target);
        for (List<Integer> pair : res) {
            System.out.println(pair.get(0) + " " + pair.get(1));
        }
    }
}
Python
def distinctPairs(arr, target):
    res = []
    n = len(arr)
    
    # frequency map to store the frequency of all elements
    freq = {}

    for i in range(n):
        complement = target - arr[i]
        
        # If the complement is equal to arr[i], then there should
        # be only one occurrence of complement in the hash map
        if complement == arr[i]:
            if freq.get(complement, 0) == 1: 
                res.append([arr[i], arr[i]])
        
        # if complement is not equal to arr[i], then there should
        # be at least one occurrence of complement and no occurrence
        # of current element in the hash map
        elif freq.get(complement, 0) > 0 and freq.get(arr[i], 0) == 0:
            first = min(arr[i], complement)
            second = max(arr[i], complement)
            res.append([first, second])
        
        freq[arr[i]] = freq.get(arr[i], 0) + 1
    
    return res


if __name__ == "__main__":
    arr = [1, 5, 7, -1, 5]
    target = 6
    
    res = distinctPairs(arr, target)
    for pair in res:
        print(pair[0], pair[1])
C#
using System;
using System.Collections.Generic;

class GfG {
    static List<List<int>> distinctPairs(List<int> arr, int target) {
        List<List<int>> res = new List<List<int>>();
        int n = arr.Count;

        Dictionary<int, int> freq = new Dictionary<int, int>();

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

            // If the complement is equal to arr[i], then there should
            // be only one occurrence of complement in the hash map
            if (complement == arr[i]) {
                if (freq.GetValueOrDefault(complement, 0) == 1)
                    res.Add(new List<int> { arr[i], arr[i] });
            }
          
            // if complement is not equal to arr[i], then there should
            // be at least one occurrence of complement and no occurrence
            // of current element in the hash map
            else if (freq.GetValueOrDefault(complement, 0) > 0 
                     		&& freq.GetValueOrDefault(arr[i], 0) == 0) {
                int first = Math.Min(arr[i], complement);
                int second = Math.Max(arr[i], complement);
                res.Add(new List<int> { first, second });
            }

            freq[arr[i]] = freq.GetValueOrDefault(arr[i], 0) + 1;
        }

        return res;
    }

    static void Main(string[] args) {
        List<int> arr = new List<int> { 1, 5, 7, -1, 5 };
        int target = 6;

        List<List<int>> res = distinctPairs(arr, target);
        foreach (var pair in res)
            Console.WriteLine($"{pair[0]} {pair[1]}");
    }
}
JavaScript
function distinctPairs(arr, target) {
    let res = [];
    let n = arr.length;
    
    let freq = new Map();

    for (let i = 0; i < n; i++) {
        let complement = target - arr[i];
      
        // If the complement is equal to arr[i], then there should
        // be only one occurrence of complement in the hash map
        if (complement === arr[i]) {
            if (freq.get(complement) === 1) 
                res.push([arr[i], arr[i]]);
        }
      
        // if complement is not equal to arr[i], then there should
        // be at least one occurrence of complement and no occurrence
        // of current element in the hash map
        else if (freq.get(complement) > 0 && freq.get(arr[i]) === undefined) {
            let first = Math.min(arr[i], complement);
            let second = Math.max(arr[i], complement);
            res.push([first, second]);
        }
      
        freq.set(arr[i], (freq.get(arr[i]) || 0) + 1);
    }
  
    return res;
}

const arr = [1, 5, 7, -1, 5];
const target = 6;

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

Output
1 5
-1 7

Time Complexity: O(n)
Auxiliary Space: O(n)

Note:In the rare case of severe hash collisions in the unordered_map, operations degrade to O(n), making the overall complexity O(n²).


Article Tags :

Explore