Lesson 75 of 164
Find Two Pairs Such That a + b = c + d
Given an array of distinct integers, find two pairs (a, b) and (c, d) such that a + b = c + d, where a, b, c, and d are four different elements. Return any such two pairs, or Optional.empty() if there aren't any. Optional is a container that holds either one value or nothing; here it holds an int[] {a, b, c, d}.
Example 1
Input: [3, 4, 7, 1, 12, 9]
Output: (4, 12) and (7, 9) both sum to 16
(3, 7) and (1, 9), both summing to 10, is also validExample 2
Input: [1, 2, 4]
Output: empty (the sums are 3, 5, and 6: all different)Brute force: try every four indices
Choose i < j for the first pair and k < l for the second, make sure all four indices are different, and compare the sums.
import java.util.Optional;
public class Main {
static Optional<int[]> findPairs(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = i + 1; k < n; k++) {
for (int l = k + 1; l < n; l++) {
if (k != j && l != j && nums[i] + nums[j] == nums[k] + nums[l]) {
return Optional.of(new int[]{nums[i], nums[j], nums[k], nums[l]});
}
}
}
}
}
return Optional.empty();
}
static String show(Optional<int[]> r) {
return r.map(x -> "((" + x[0] + ", " + x[1] + "), (" + x[2] + ", " + x[3] + "))").orElse("none");
}
public static void main(String[] args) {
System.out.println(show(findPairs(new int[]{3, 4, 7, 1, 12, 9})));
System.out.println(show(findPairs(new int[]{1, 2, 4})));
}
}((3, 7), (1, 9))
noneTime: O(n⁴). Space: O(1).
Starting k at i + 1 keeps the first pair's smallest index i below both indices of the second pair, so each combination is checked only once.
Optimal: a HashMap from each sum to a pair
Enumerate all pairs (i, j) once and compute their sums. Store sum → (i, j) in a HashMap. If a sum is already in the map, the stored pair and the current pair have the same sum.
The two pairs can't share an element: if a + b = a + d, then b = d, and all values are distinct. So a repeated sum always gives four different elements.
Walkthrough with [3, 4, 7, 1, 12, 9]:
| pair (values) | sum | sum already in map? |
|---|---|---|
| (3, 4) | 7 | no, store |
| (3, 7) | 10 | no, store |
| (3, 1) | 4 | no, store |
| (3, 12) | 15 | no, store |
| (3, 9) | 12 | no, store |
| (4, 7) | 11 | no, store |
| (4, 1) | 5 | no, store |
| (4, 12) | 16 | no, store |
| (4, 9) | 13 | no, store |
| (7, 1) | 8 | no, store |
| (7, 12) | 19 | no, store |
| (7, 9) | 16 | yes: (4, 12) → return (4, 12), (7, 9) |
The map value is an int[] {i, j} holding the two indices.
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class Main {
static Optional<int[]> findPairs(int[] nums) {
Map<Integer, int[]> bySum = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
int sum = nums[i] + nums[j];
int[] earlier = bySum.get(sum);
if (earlier != null) {
return Optional.of(new int[]{nums[earlier[0]], nums[earlier[1]], nums[i], nums[j]});
}
bySum.put(sum, new int[]{i, j});
}
}
return Optional.empty();
}
static String show(Optional<int[]> r) {
return r.map(x -> "((" + x[0] + ", " + x[1] + "), (" + x[2] + ", " + x[3] + "))").orElse("none");
}
public static void main(String[] args) {
System.out.println(show(findPairs(new int[]{3, 4, 7, 1, 12, 9})));
System.out.println(show(findPairs(new int[]{1, 2, 4})));
System.out.println(show(findPairs(new int[]{})));
}
}((4, 12), (7, 9))
none
noneTime: O(n²): there are n(n-1)/2 pairs, each with an O(1) map operation. Space: O(n²) for the map in the worst case.
The two solutions return different answers because they enumerate the combinations in a different order. Both answers are valid.
The map stores indices, not values. With duplicate values allowed, you'd need them to check that the four positions are different, for example k != i && k != j && l != i && l != j.
Edge cases
- Fewer than 4 elements: no answer is possible.
- Overflow:
nums[i] + nums[j]wraps around silently inintarithmetic for large values. Compute sums aslong(withMap<Long, int[]>) if the range requires it.
