Array · 7 of 36
Find all pairs on integer array whose sum is equal to given number
Find every pair of numbers in a list that adds up to a target, by remembering what you have already seen.
- Simple way
- time O(n^2)
room O(1) - Clever way
- time O(n + p)
room O(n)
The problem, simply
You get an array of whole numbers and a target number. Find every pair of positions i < j where arr[i] + arr[j] equals the target.
The same value can sit at two positions, and each position counts on its own. In [1, 5, 7, -1, 5] with target 6, the 1 pairs with both 5s, so (1, 5) shows up twice. Give back the pairs (or how many there are).
A story to remember it
Picture it
Target 6. The 1 at index 0 pairs with the 5 at index 1 and with the 5 at index 4. The 7 pairs with the -1.
- checking
- answer
Examples
A normal case
- In
arr = [1, 5, 7, -1, 5], target = 6- Out
(1, 5), (7, -1), (1, 5): 3 pairs
The 1 pairs with each 5, and 7 + (-1) = 6.
All the same
- In
arr = [1, 1, 1, 1], target = 2- Out
6 pairs
Every two of the four 1s make a pair: 4 * 3 / 2 = 6. This is why we store a count, not only yes or no.
Negatives and zeros
- In
arr = [-3, 3, 0, 0], target = 0- Out
(-3, 3), (0, 0): 2 pairs
A number can pair with its own value at another position, like the two 0s.
No pairs
- In
arr = [1, 2, 3], target = 10- Out
0 pairs
The biggest two only make 5. Return an empty list.
Way 1: the simple way
Try every pair of positions and keep the ones that add up to the target.
- For each
i, for eachj > i, checkarr[i] + arr[j] == target. - If yes, add the pair.
class Solution {
public List<int[]> findPairs(int[] arr, int target) {
List<int[]> pairs = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] + arr[j] == target) {
pairs.add(new int[] { arr[i], arr[j] });
}
}
}
return pairs;
}
}How long it takes: every pair once, O(n^2). Extra room: nothing besides the answer, O(1).
Way 2: the clever way
Walk left to right with a board that counts how many times each number has appeared so far (a hash map).
- For the number
xin front of you, the partner you need isneed = target - x. - Look up
needon the board. If it was seenctimes, that iscnew pairs. - Then add
xto the board. Doing it after the lookup stops a number from pairing with itself.
Each card asks the board for its partner
01 / 07
Start with an empty board. We want pairs that add up to 6.
- target
- 6
- pairs
- 0
- looking now
- done
- answer
- just added
class Solution {
public List<int[]> findPairs(int[] arr, int target) {
List<int[]> pairs = new ArrayList<>();
Map<Integer, Integer> seen = new HashMap<>(); // number -> how many times so far
for (int x : arr) {
int need = target - x;
int c = seen.getOrDefault(need, 0);
for (int k = 0; k < c; k++) {
pairs.add(new int[] { need, x }); // one pair per earlier partner
}
seen.merge(x, 1, Integer::sum); // now write x on the board
}
return pairs;
}
// If only the number of pairs is wanted, this is O(n) no matter how many pairs exist.
public long countPairs(int[] arr, int target) {
Map<Integer, Integer> seen = new HashMap<>();
long count = 0;
for (int x : arr) {
count += seen.getOrDefault(target - x, 0);
seen.merge(x, 1, Integer::sum);
}
return count;
}
}How long it takes: one walk with a quick board lookup per number, plus writing out the p pairs, so O(n + p). Counting alone is O(n). Extra room: the board holds up to n numbers, O(n).
Watch out for
- Use counts, not a plain set, when duplicates matter. A set would find only one pair in
[1, 1, 1, 1]with target 2. target - xcan overflow for values near theintlimits. Uselongif the input can be that large.- Ask the interviewer: do they want every pair of positions, or only different value pairs?
(1, 5)twice versus once changes the code.
What interviewers ask next
- Only distinct value pairs? Sort, then use two pointers from both ends. When the sum matches, record it and skip all copies of both values.
O(n log n)time,O(1)extra room. - Return the indices of one pair (LeetCode Two Sum)? Store index instead of count, and return as soon as
needis found. - Pairs with difference
k? Look upx - kandx + kinstead oftarget - x. - The array is too big for memory? Sort it on disk, then stream it from both ends with two pointers.
- Three numbers that add up to a target? Fix one number, then run this pair search on the rest.
O(n^2).
Remember this
Grown-up words: the whiteboard is a hash map from value to count, the partner is the complement target - x, and this is the classic Two Sum pattern.