Two Sum
Problem
Read an array and a target k. Find two different positions i < j with a[i] + a[j] = k. If many pairs exist, print the pair with the smallest i (then the smallest j). Print i and j separated by a space, or none if there is no pair.
Constraints
- 2 <= n <= 10^5
Examples
Input
4 2 7 11 15 9
Output
0 1
Solutions
For each element we look up its partner k - a[j] in a map of earlier elements. This is one pass instead of two nested loops.
/*
* Problem : Process an array and a number k.
* Input : n, then n integers, then k.
* Output : Indexes i and j or none.
* Approach: Use a hash map.
* Time : O(n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String solve(int[] a, int k) {
// Step 1: Remember the index of every value we have seen. Key = value, value = index.
java.util.Map<Integer, Integer> seen = new java.util.HashMap<>();
int bestI = -1;
int bestJ = -1;
for (int j = 0; j < a.length; j++) {
// Step 2: The partner of a[j] is k - a[j]. Did we see it before?
Integer i = seen.get(k - a[j]);
if (i != null && (bestI == -1 || i < bestI || (i == bestI && j < bestJ))) {
bestI = i;
bestJ = j;
}
// Step 3: Keep the FIRST index of each value, so we get the smallest i.
seen.putIfAbsent(a[j], j);
}
return bestI == -1 ? "none" : bestI + " " + bestJ;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = scanner.nextInt();
}
int k = scanner.nextInt();
System.out.println(solve(a, k));
}
}
Hints (1)
- What number must be paired with a[j]?