Lesson 32 of 107 6 minBestseller

Two Sum II: Input Array Is Sorted (Two Pointers)

Master the optimal two-pointer approach to find a pair that sums to a target in a sorted array. Learn the "Squeeze" intuition and interview scripts.

Reading Mode

Hide the curriculum rail and keep the lesson centered for focused reading.

Key Takeaways

  • If your current Sum is **too small**, you need to increase it. The only way to increase it without c
  • If your current Sum is **too large**, you need to decrease it. You move your Large pointer backward.
  • [Problem: 3Sum - Unique Triplets](/blog/problem-3sum-unique-triplets/)
Recommended Prerequisites
Two Pointers Pattern Mastery

Premium outcome

Patterns, mental models, and interview-grade execution in one path.

Engineers targeting product-company interviews with high algorithmic rigor.

What you unlock

  • Pattern-first mastery across arrays, trees, graphs, DP, and greedy problems
  • A clean progression from theory to representative interview questions
  • Better verbal explanations and solution-structuring under pressure

1. Problem Statement

Mental Model

Imposing order to reduce the search space complexity.

Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number.

Return the indices of the two numbers, index1 and index2, added by one as an integer array [index1, index2] of length 2.

Input: numbers = [2,7,11,15], target = 9
Output: [1,2]

2. The Mental Model: The "Squeeze" Intuition

Why do we use two pointers here? Because the array is Sorted.

Imagine you are standing in a hallway. The smallest values are behind you (index 0) and the largest are in front of you (index N-1).

  • If your current "Sum" is too small, you need to increase it. The only way to increase it without checking every pair is to move your "Small" pointer forward.
  • If your current "Sum" is too large, you need to decrease it. You move your "Large" pointer backward.

This property of Monotonicity (moving a pointer always changes the sum in a predictable direction) is what allows us to solve this in $O(N)$ instead of $O(N^2)$.

3. Visual Execution

flowchart LR
    Start[2, 7, 11, 15] --> P1[L=2, R=15 | Sum=17]
    P1 -- Sum > Target --> P2[L=2, R=11 | Sum=13]
    P2 -- Sum > Target --> P3[L=2, R=7 | Sum=9]
    P3 -- Sum == Target --> Found[Return 1, 2]

4. Java Implementation

public int[] twoSum(int[] numbers, int target) {
    int left = 0;
    int right = numbers.length - 1;
    
    while (left < right) {
        int sum = numbers[left] + numbers[right];
        
        if (sum == target) {
            return new int[]{left + 1, right + 1};
        } else if (sum < target) {
            left++; // Need a larger sum
        } else {
            right--; // Need a smaller sum
        }
    }
    return new int[]{-1, -1};
}

5. Verbal Interview Script (The Staff Way)

Interviewer: "How would you solve Two Sum if the array is already sorted?"

You: "Since the array is sorted, I can leverage the monotonic property of the input. Instead of a HashMap which takes $O(N)$ space, I'll use a Two-Pointer 'Squeeze' approach. I'll place one pointer at the start and one at the end. By calculating the sum and comparing it to the target, I can greedily decide which pointer to move. If the sum is less than the target, I increment the left pointer to bring in a larger value. If it's greater, I decrement the right pointer. This gives us a time complexity of $O(N)$ and a space complexity of $O(1)$, which is optimal."

6. Common Pitfalls & Edge Cases

  1. Integer Overflow: In some languages, numbers[left] + numbers[right] might overflow. In Java, if the target and numbers are large, consider using long for the sum check.
  2. 1-Indexed vs 0-Indexed: Always clarify if the interviewer wants the array indices (0-based) or the human-readable positions (1-based). This problem specifically asks for 1-based.
  3. No Solution: Even if the problem says a solution exists, a senior engineer always adds a default return [-1, -1] to make the code robust.

7. Comparative Analysis

Approach Time Space Note
Brute Force $O(N^2)$ $O(1)$ Check every pair.
HashMap $O(N)$ $O(N)$ Good if array is NOT sorted.
Two Pointers $O(N)$ $O(1)$ Best for sorted arrays.

5. Verbal Interview Script (Staff Tier)

Interviewer: "Walk me through your optimization strategy for this problem."

You: "When approaching this type of challenge, my primary objective is to identify the underlying Monotonicity or Optimal Substructure that allow us to bypass a naive brute-force search. In my implementation of 'Two Sum II: Input Array Is Sorted (Two Pointers)', I focused on reducing the time complexity by leveraging a HashMap-based lookup. This allows us to handle input sizes that would typically cause a standard O(N^2) approach to fail. Furthermore, I prioritized memory efficiency by using in-place modifications. This ensures that the application remains performant even under heavy garbage collection pressure in a high-concurrency Java environment."

6. Staff-Level Interview Follow-Ups

Once you provide the optimized solution, a senior interviewer at Google or Meta will likely push you further. Here is how to handle the most common follow-ups:

Follow-up 1: "How does this scale to a Distributed System?"

If the input data is too large to fit on a single machine (e.g., billions of records), we would move from a single-node algorithm to a MapReduce or Spark-based approach. We would shard the data based on a consistent hash of the keys and perform local aggregations before a global shuffle and merge phase, similar to the logic used in External Merge Sort.

Follow-up 2: "What are the Concurrency implications?"

In a multi-threaded Java environment, we must ensure that our state (e.g., the DP table or the frequency map) is thread-safe. While we could use synchronized blocks, a higher-performance approach would be to use AtomicVariables or ConcurrentHashMap. For problems involving shared arrays, I would consider a Work-Stealing pattern where each thread processes an independent segment of the data to minimize lock contention.

7. Performance Nuances (The Java Perspective)

  1. Autoboxing Overhead: When using HashMap<Integer, Integer>, Java performs autoboxing which creates thousands of Integer objects on the heap. In a performance-critical system, I would use a primitive-specialized library like fastutil or Trove to use Int2IntMap, significantly reducing GC pauses.
  2. Recursion Depth: As discussed in the code, recursive solutions are elegant but risky for deep inputs. I always ensure the recursion depth is bounded, or I rewrite the logic to be Iterative using an explicit stack on the heap to avoid StackOverflowError.

Key Takeaways

  • If your current "Sum" is too small, you need to increase it. The only way to increase it without checking every pair is to move your "Small" pointer forward.
  • If your current "Sum" is too large, you need to decrease it. You move your "Large" pointer backward.
  • Problem: 3Sum - Unique Triplets

Want to track your progress?

Sign in to save your progress, track completed lessons, and pick up where you left off.