2 Sum – All distinct pairs with given sum (original) (raw)

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.

Table of Content

[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 #include #include using namespace std; vector<vector> distinctPairs(vector &arr, int target) { vector<vector> 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 arr = {1, 5, 7, -1, 5}; int target = 6; vector<vector> 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> distinctPairs(int[] arr, int target) { List<List> 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 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> distinctPairs(int[] arr, int target) { List<List> res = new List<List>(); 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]);

`

**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 #include using namespace std; vector<vector> distinctPairs(vector &arr, int target) { vector<vector> res; int n = arr.size(); set<vector> 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 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 arr = {1, 5, 7, -1, 5}; int target = 6; vector<vector> 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]));

`

**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:

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

C++ `

#include #include

using namespace std; vector<vector> distinctPairs(vector &arr, int target) { vector<vector> 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 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> distinctPairs(int[] arr, int target) { List<List> 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> DistinctPairs(int[] arr, int target) { List<List> res = new List<List>(); 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]);

`

**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 :

**When arr[i] != complement :

#include #include #include using namespace std;

vector<vector> distinctPairs(vector &arr, int target) { vector<vector> 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 arr = {1, 5, 7, -1, 5}; int target = 6; vector<vector> res = distinctPairs(arr, target); for (vector &pair : res) cout << pair[0] << " " << pair[1] << endl;

return 0;

}

Java

import java.util.*; class GfG { static List<List> distinctPairs(int[] arr, int target) { List<List> 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> distinctPairs(List arr, int target) { List<List> res = new List<List>(); 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]); }

`

**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²).