2 Sum – All distinct pairs with given sum
Last Updated :
01 Sep, 2025
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]);
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]));
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]);
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]);
}
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²).
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem