Solve two-sum variants at scale
Company: Amazon
Role: Data Scientist
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Onsite
Quick Answer: This question evaluates array and hashing algorithms, pair-sum reasoning including duplicate handling and lexicographic minimality, streaming and external-memory algorithm design, trade-offs in time/space complexity, and extension to three-sum with deduplication.
Two-Sum: lexicographically smallest index pair
Constraints
- 0 <= len(nums) <= 10^5
- -10^9 <= nums[i], target <= 10^9
- Indices are 0-based and the returned pair must satisfy i < j
- Return [] when no valid pair exists
Examples
Input: ([3, 1, 2, 2, 4], 4)
Expected Output: [0, 1]
Explanation: nums[0]+nums[1]=3+1=4. Pair (2,3)=2+2=4 also works but (0,1) is lexicographically smaller.
Input: ([2, 7, 11, 15], 9)
Expected Output: [0, 1]
Explanation: 2+7=9.
Input: ([3, 3], 6)
Expected Output: [0, 1]
Explanation: Duplicate values: first 3 stored at index 0, second 3 at index 1 finds complement.
Input: ([1, 2, 3], 7)
Expected Output: []
Explanation: No pair sums to 7.
Input: ([], 5)
Expected Output: []
Explanation: Empty input.
Input: ([5], 5)
Expected Output: []
Explanation: A single element cannot form a pair.
Input: ([0, 4, 3, 0], 0)
Expected Output: [0, 3]
Explanation: Two zeros at indices 0 and 3 sum to 0; the earliest-index zero is paired with the next matching zero.
Input: ([-3, 4, 3, 90], 0)
Expected Output: [0, 2]
Explanation: -3 + 3 = 0; works with negatives.
Input: ([1, 1, 1, 1], 2)
Expected Output: [0, 1]
Explanation: First two 1s give the lexicographically smallest pair.
Hints
- A single pass with a hash map from value -> earliest index gives O(n) time.
- Store only the FIRST index at which each value occurs so the matching i is as small as possible.
- Scanning j from left to right and taking the first complement hit yields the lexicographically smallest (i, j).
Follow-up 1 - Sorted array two-sum in O(1) extra space
Constraints
- nums is sorted in non-decreasing order
- 0 <= len(nums) <= 10^5
- -10^9 <= nums[i], target <= 10^9
- Return [] when no valid pair exists
Examples
Input: ([1, 2, 2, 3, 4], 4)
Expected Output: [0, 3]
Explanation: nums[0]+nums[3]=1+3=4 after the right pointer steps in from value 4.
Input: ([2, 7, 11, 15], 9)
Expected Output: [0, 1]
Explanation: 2+7=9 at the leftmost two elements.
Input: ([1, 3, 4, 5, 7, 11], 9)
Expected Output: [2, 3]
Explanation: Pointers converge to 4+5=9.
Input: ([-3, 0, 3, 4, 90], 0)
Expected Output: [0, 2]
Explanation: -3+3=0; works with negatives in a sorted array.
Input: ([1, 2, 3], 7)
Expected Output: []
Explanation: No pair reaches 7.
Input: ([], 5)
Expected Output: []
Explanation: Empty input.
Input: ([5], 5)
Expected Output: []
Explanation: Single element cannot pair.
Input: ([1, 1, 1, 1], 2)
Expected Output: [0, 3]
Explanation: With all-equal values the two-pointer meets equality immediately at the outermost indices [0,3].
Input: ([2, 3, 4], 6)
Expected Output: [0, 2]
Explanation: 2+4=6 at the two ends.
Hints
- Place one pointer at each end and move them inward based on the comparison of the current sum to target.
- Sorted order makes the sum monotone in each move, so a too-small sum means advance the left pointer and a too-large sum means retreat the right pointer.
- On the first equality you may return immediately; with duplicate values this gives a valid outermost pair, not necessarily the smallest indices.
Follow-up 4 - Three-sum on a sorted array (unique triplets)
Constraints
- 0 <= len(nums) <= 3000
- -10^9 <= nums[i], target <= 10^9
- Triplets are value triplets (multisets), deduplicated
- Each triplet is returned in non-decreasing order and the overall list is sorted ascending
Examples
Input: ([-1, 0, 1, 2, -1, -4], 0)
Expected Output: [[-1, -1, 2], [-1, 0, 1]]
Explanation: Classic 3-sum=0: the two distinct triplets after dedup of the repeated -1.
Input: ([0, 0, 0, 0], 0)
Expected Output: [[0, 0, 0]]
Explanation: All zeros yield a single deduplicated triplet.
Input: ([1, 2, 3, 4, 5], 9)
Expected Output: [[1, 3, 5], [2, 3, 4]]
Explanation: Two triplets sum to 9.
Input: ([0, 1, 1], 2)
Expected Output: [[0, 1, 1]]
Explanation: 0+1+1=2 is a valid triplet.
Input: ([], 0)
Expected Output: []
Explanation: Empty input.
Input: ([1, 2], 3)
Expected Output: []
Explanation: Fewer than three elements.
Input: ([-2, 0, 1, 1, 2], 0)
Expected Output: [[-2, 0, 2], [-2, 1, 1]]
Explanation: Dedup of the repeated 1 keeps one [-2,1,1].
Input: ([3, 3, 3, 0, 0, 0], 9)
Expected Output: [[3, 3, 3]]
Explanation: Only the three 3s reach 9; deduplicated to one triplet.
Input: ([-4, -2, -1, 0, 1, 2, 3], 0)
Expected Output: [[-4, 1, 3], [-2, -1, 3], [-2, 0, 2], [-1, 0, 1]]
Explanation: Four distinct triplets sum to 0 across negatives and positives.
Hints
- Sort first; then fix the smallest element and run a two-pointer two-sum on the remaining suffix.
- Skip duplicate values for the fixed index to avoid emitting the same triplet from a different starting position.
- After recording a match, advance the left pointer past equal values and retreat the right pointer past equal values to deduplicate.