Top Interview Patterns

[!NOTE] This module explores the core principles of Top Interview Patterns, deriving solutions from first principles and hardware constraints to build world-class, production-ready expertise.

1. The Meta-Game

Coding interviews are not just about writing code that compiles. They are a role-playing game where you act as a “Senior Engineer” solving a problem with a peer. The interviewer is not just looking for the right answer; they are looking for Signal—evidence of how you think, communicate, and handle ambiguity.

Why Patterns Matter

Memorizing 500 individual LeetCode problems is a losing strategy. The human brain is not optimized for raw, unstructured data retrieval under stress. Instead, we are pattern-matching machines. By mastering a core set of ~15 algorithmic patterns, you can map 90% of unseen interview problems to a known mental model.

Think of patterns as architectural blueprints. You don’t memorize every house in a city; you understand how a foundation, walls, and a roof fit together. When asked to build a new house, you apply those structural patterns.


2. The 4 Pillars of Interviewing

Successful interviews follow a predictable structure. Mastering the technical patterns is only half the battle; executing them within this framework is what secures the offer.

Pillar Focus The Signal
1. Clarification Constraint Hunting “Does this candidate dive in blind, or do they de-risk the problem first by finding edge cases?”
2. Algorithm Verbal Design “Can they communicate complex logic simply, evaluating trade-offs before writing a single line of code?”
3. Coding Translation Speed “Can they translate their verbal algorithm into clean, modular, and bug-free code efficiently?”
4. Verification Self-Testing “Do they dry-run their code and find their own bugs, or do they rely on the interviewer as a compiler?”

3. The Sliding Window

The Analogy: Imagine you are a photographer trying to capture the perfect panoramic shot of a mountain range. Your camera lens has a fixed width. As you pan from left to right, a new mountain enters the right side of the frame, and an old mountain leaves the left side. You don’t need to retake the entire photo every time you move one step; you only update the edges.

Use Case: Problems involving contiguous subarrays or substrings (e.g., “Find the maximum sum of a subarray of size K” or “Find the longest substring without repeating characters”).

Fixed Size Window

  1. Expand: Add the element at the right pointer to your window state.
  2. Slide: If the window size exceeds K, remove the element at the left pointer and increment left.

Variable Size Window

  1. Expand: Move right to expand the window until the specific condition is met (e.g., sum ≥ target).
  2. Shrink: Move left to shrink the window, updating your optimal answer (like minimum length) as long as the condition holds.

Interactive: Variable Sliding Window

Find the smallest subarray with sum ≥ 7.

Current Sum: 0
Min Length: Infinity

4. Two Pointers

The Analogy: Imagine you are trying to find two books in a library that together cost exactly $50. If the books are randomly scattered, you have to check every pair (O(N²)). But if the books are sorted by price on a single shelf, you can put one hand on the cheapest book and one hand on the most expensive. If their sum is too high, move your right hand to a cheaper book. If the sum is too low, move your left hand to a more expensive one.

Use Case: Searching pairs in Sorted Arrays, reversing arrays, or comparing two different arrays. Optimization: Reduces O(N²) time to O(N) time with O(1) space.

Core Logic (Opposite Ends)

  • Initialize left at index 0, right at the last index.
  • Too Small? Increment left to increase the sum.
  • Too Big? Decrement right to decrease the sum.

5. Fast & Slow Pointers (Tortoise & Hare)

The Analogy: Imagine a running track. If two runners start at the same time, but Runner B is twice as fast as Runner A, Runner B will eventually lap Runner A. If the track is a straight line, Runner B simply finishes first. But if the track has a loop (a cycle), they are guaranteed to meet at some point on the track.

Use Case: Detecting cycles in Linked Lists or Arrays, finding the middle of a Linked List, or finding the start of a cycle.

Floyd’s Cycle-Finding Algorithm

  • Initialize: Both slow and fast point to the head of the list.
  • Move: slow moves 1 step. fast moves 2 steps.
  • Detect: If they ever point to the same node, a Cycle Exists.
  • Terminate: If fast or fast.next reaches null, there is no cycle.

6. Monotonic Stack

The Analogy: Imagine people lining up for a rollercoaster, where you can only see the people in front of you who are strictly taller than you. Anyone shorter is hidden by the taller person. A monotonic stack enforces this “line of sight” by systematically kicking out elements that break the ordered invariant.

Use Case: Problems asking for the “Next Greater Element”, “Next Smaller Element”, or computing areas under histograms (e.g., Trapping Rain Water, Largest Rectangle in Histogram).

Core Constraint

Maintain the stack in a strictly increasing or strictly decreasing order.

  • For Next Greater Element (decreasing stack): Before pushing element X, pop all elements from the stack that are strictly less than X. For all those popped elements, X is their next greater element.

7. Code Example: Sliding Window (Variable)

Here is a concrete implementation of the sliding window pattern we visualized earlier. We shrink the window aggressively from the left whenever the validity condition (sum >= target) is met.

// Find min length subarray with sum >= target
public int minSubArrayLen(int target, int[] nums) {
  int left = 0, sum = 0, minLen = Integer.MAX_VALUE;

  for (int right = 0; right < nums.length; right++) {
    sum += nums[right]; // 1. Expand the window

    // 2. Shrink window while the condition holds
    while (sum >= target) {
      minLen = Math.min(minLen, right - left + 1); // Update best answer
      sum -= nums[left];
      left++;
    }
  }
  return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
func minSubArrayLen(target int, nums []int) int {
  left, sum := 0, 0
  minLen := len(nums) + 1

  for right, val := range nums {
    sum += val // 1. Expand

    // 2. Shrink
    for sum >= target {
      if right - left + 1 < minLen {
        minLen = right - left + 1
      }
      sum -= nums[left]
      left++
    }
  }

  if minLen > len(nums) { return 0 }
  return minLen
}

8. Deep Dive Strategy Lab: Patterns

Intuition Through First Principles

Think of this chapter like solving under whiteboard time pressure. The goal is not to memorize a fixed trick, but to repeatedly answer these fundamental questions when faced with a new problem:

  1. What is the naive bottleneck? (e.g., nested loops resulting in O(N²)).
  2. Which constraint dominates? Is the array sorted? Does it contain only positive numbers?
  3. Which representation eliminates the bottleneck?
    • If contiguous and positive, sliding window eliminates redundant sums.
    • If sorted, two pointers eliminate impossible pair combinations.
    • If cyclic, two speeds eliminate O(N) visited hash sets.

By framing problems this way, you shift from remembering algorithms to discovering them naturally.