Common Coding Interview Patterns

Master the essential patterns—sliding window, two pointers, fast-slow pointers—that solve 80% of linked list and array problems.

published: reading time: 13 min read author: GeekWorkBench

Common Coding Interview Patterns

Most coding interview problems fall into recognizable patterns. Once you internalize these patterns, you’ll see them everywhere and know immediately which approach fits. These patterns show up everywhere once you know to look for them: sliding window for subarray/substring problems, two pointers for pair problems in sorted arrays, fast-slow pointers for cycle detection, and merge intervals for overlapping ranges. Knowing these five patterns handles most easy and medium difficulty problems.

The interviewer’s goal isn’t to stump you—it’s to see how you think. Naming the pattern you recognize shows experience, and explaining why you’re choosing an approach demonstrates reasoning. Don’t jump straight to coding; spend 30 seconds outlining your approach first.

Introduction

Pattern 1: Sliding Window

When: Subarray/substring problems asking for max, min, or average.

def max_subarray_sum_k(arr, k):
    """Find maximum sum of subarray with exactly k elements."""
    window_sum = sum(arr[:k])
    max_sum = window_sum

    for i in range(k, len(arr)):
        window_sum += arr[i] - arr[i - k]
        max_sum = max(max_sum, window_sum)

    return max_sum

Variations:

  • Fixed size k: expand by 1, shrink by 1
  • Variable size: expand freely, contract when constraint violated

Pattern 2: Two Pointers (Opposite Ends)

When: Pair problems in sorted arrays, palindrome checks.

def pair_sum_sorted(arr, target):
    """Find pair with target sum in sorted array."""
    left, right = 0, len(arr) - 1

    while left < right:
        current = arr[left] + arr[right]
        if current == target:
            return [left, right]
        elif current < target:
            left += 1
        else:
            right -= 1

    return [-1, -1]

Key: Move left rightward to increase sum, right leftward to decrease.

Pattern 3: Fast-Slow Pointers

When: Cycle detection, finding middle, linked list problems.

def has_cycle(head):
    """Detect cycle in linked list using Floyd's algorithm."""
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True
    return False

def find_middle(head):
    """Find middle node of linked list."""
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
    return slow

Pattern 4: Merge Intervals

When: Overlapping intervals, scheduling, resource allocation.

def merge_intervals(intervals):
    """Merge all overlapping intervals."""
    if not intervals:
        return []

    intervals.sort(key=lambda x: x[0])
    merged = [intervals[0]]

    for start, end in intervals[1:]:
        if start <= merged[-1][1]:
            merged[-1][1] = max(merged[-1][1], end)
        else:
            merged.append([start, end])

    return merged

Pattern 5: BFS on Graphs

When: Shortest path in unweighted graph, level-order traversal.

from collections import deque

def shortest_path(graph, start, end):
    """BFS finds shortest path in unweighted graph."""
    queue = deque([(start, [start])])
    visited = {start}

    while queue:
        node, path = queue.popleft()
        if node == end:
            return path

        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append((neighbor, path + [neighbor]))

    return None

Quick Recap Checklist

  • Sliding window: subarray sum/average with fixed/variable window
  • Two pointers: sorted array pairs, palindrome (opposite ends)
  • Fast-slow: cycle detection, middle element (same start, different speeds)
  • Merge intervals: sort by start, merge overlaps
  • BFS: shortest path in unweighted graph

Deep Dives

Why Sliding Window Works

The sliding window transforms O(n²) brute force into O(n) by reusing previous computations. When you calculate sum(arr[i-k+1:i+1]) from scratch each iteration, you repeat k-1 additions unnecessarily. The window slides by subtracting the outgoing element and adding the incoming one — a constant-time operation. This works because the window maintains contiguous elements with guaranteed O(1) shift.

Two Pointers on Sorted Data

Two pointers exploit sorted data’s ordering property. When left moves right, the sum increases monotonically; when right moves left, the sum decreases. This monotonicity guarantees you never miss a valid pair — you explore exactly n combinations, not n². Uniqueness of pairs requires additional visited tracking.

Floyd’s Algorithm Convergence Proof

For cycle detection, if the cycle length is λ and the hare moves 2x fast while the tortoise moves 1x slow, they meet after at most λ steps inside the cycle. Proof: In λ steps, the hare completes exactly 2 full laps (2λ steps) while the tortoise completes 1 lap (λ steps). Since they start λ steps apart on a λ-cycle, they must meet. The meeting point is guaranteed before the hare laps the tortoise.

Real-world Failure Scenarios

ScenarioWhat Went WrongLesson
Amazon OA: Maximum subarray sumTried to use divide-and-conquer when sliding window was simplerMatch pattern to problem structure first
Google Phone Interview: Palindrome checkUsed string reverse instead of two pointersAvoided O(n) extra space when O(1) was possible
Meta Onsite: Course schedule problemForgot to track visited nodes in BFSAlways track visited/discovered nodes in graphs
Stripe Interview: Merge overlapping meetingsSkipped sorting step due to time pressureSort first — it’s often half the algorithm
Netflix Interview: Longest substring with k distinctFailed to shrink window when constraint violatedVariable-size windows need explicit contraction logic

Trade-off Analysis

PatternTimeSpaceBest ForLimitation
Sliding Window (fixed)O(n)O(1)Subarray sums, averagesOnly works when window size is predetermined
Sliding Window (variable)O(n)O(1)Longest substring with constraintRequires clear contraction condition
Two PointersO(n)O(1)Pair sums in sorted arraysInput must be sorted; doesn’t find all pairs in unsorted
Fast-Slow PointersO(n)O(1)Cycle detection, middle elementOnly detects presence, not position
Merge IntervalsO(n log n)O(n)Scheduling, resource allocationRequires sorting; O(n) space for output
BFSO(V+E)O(V)Shortest path, level orderDoesn’t handle weighted edges; exponential space in worst case

Interview Questions

1. How do you decide which pattern to use?

Ask: Is the input sorted? Two pointers (opposite ends). Does it ask about subarrays/substrings? Sliding window. Is it a linked list? Fast-slow pointers. Are there intervals/ranges? Merge intervals. Is it shortest path in unweighted graph? BFS. The problem's structure usually hints at the pattern.

2. What if a problem seems to fit multiple patterns?

Some problems require combining patterns. "Longest substring with k distinct characters" uses sliding window. "Detect cycle in linked list" uses fast-slow. A problem like "Clone graph with random pointers" might need BFS + hash map for tracking visited nodes. Start with the dominant pattern and adapt as needed.

3. When should you choose BFS over DFS for graph problems?

Expected answer points:

  • BFS for shortest path in unweighted graphs — level-order guarantees minimum edges from start
  • DFS for detecting cycles, topological sort, or when path existence is sufficient
  • Memory consideration: BFS can explode with wide graphs; DFS with deep graphs
  • Recursive DFS requires O(n) stack space; iterative BFS requires O(n) queue
4. Why does the sliding window algorithm achieve O(n) time complexity?

Expected answer points:

  • Reuses previous sum instead of recalculating from scratch each iteration
  • Each element enters and exits the window exactly once — 2n operations total
  • Constant-time update: subtract arr[i-k], add arr[i]
5. What happens if you apply two pointers to an unsorted array?

Expected answer points:

  • Two pointers work correctly only on sorted input
  • Unsorted arrays break the monotonicity guarantee — you may miss valid pairs
  • Use hash-based approach for unsorted: O(n) time, O(n) space
6. How do fast-slow pointers detect a cycle without extra space?

Expected answer points:

  • Floyd's algorithm: slow moves 1 step, fast moves 2 steps per iteration
  • If cycle exists, fast laps slow inside the cycle — they must meet
  • Meeting proves cycle existence; finding cycle start requires second phase
  • No visited set needed — O(1) space via pointer collision
7. What is the key invariant in merge intervals?

Expected answer points:

  • Sort by start time — ensures we're processing intervals in order
  • Maintain merged list where last interval's end is always the maximum end seen so far for overlapping intervals
  • If next start <= last end, extend the last interval; otherwise, start new interval
8. What is the time and space complexity of each pattern?

Expected answer points:

  • Sliding window: O(n) time, O(1) space — constant window size
  • Two pointers: O(n) time, O(1) space — sorted array traversal
  • Fast-slow pointers: O(n) time, O(1) space — cycle detection without visited set
  • Merge intervals: O(n log n) time, O(n) space — sorting dominates
  • BFS: O(V+E) time, O(V) space — queue stores all vertices at worst
9. How do you debug a failing sliding window algorithm?

Expected answer points:

  • Check window expansion: verify arr[i] is added correctly
  • Check window contraction: verify arr[i-k] is subtracted when window slides
  • Verify constraint logic for variable-size windows — shrink condition must be correct
  • Test edge cases: k=1, k=n, all same elements, empty input
10. How do you handle duplicates when using two pointers on sorted arrays?

Expected answer points:

  • Standard two pointers skip duplicates automatically — left increments past equal elements
  • For "all unique pairs" variant: add visited set to track seen values
  • For "triplets that sum to target": skip duplicate values for each pointer position
  • Key insight: sorting enables duplicate handling via position checks
11. Can merge intervals be solved iteratively without sorting?

Expected answer points:

  • No — sorting by start time is essential to the O(n log n) bottleneck
  • Without sorting, you'd need to check every pair — O(n²) worst case
  • Space-time trade-off: sorting costs O(n log n) but enables single-pass O(n) merge
  • Some interval problems like "insert interval" can use interval trees for O(log n) insertions
12. What is the maximum queue size in BFS and when does it occur?

Expected answer points:

  • Maximum queue size = maximum width of the graph at any level
  • Occurs at the level closest to the start node with most vertices
  • Worst case: star graph where center connects to all other vertices — O(V) queue
  • Line graph has maximum size of 1 — only adjacent nodes enqueued
13. Why does fast move 2x speed (not 3x or 1.5x) in Floyd's algorithm?

Expected answer points:

  • 2x guarantees convergence — any faster speed also works but wastes moves
  • 1x speed means both pointers move same pace and never meet
  • Mathematical proof: if cycle length is λ, fast laps slow within λ steps at 2x speed
  • 2 is the minimal integer speed that guarantees meeting while maximizing relative velocity
14. How do you modify two pointers to find triplets summing to zero?

Expected answer points:

  • Fix first pointer, use two pointers on remaining sorted subarray
  • Skip duplicate values for the fixed pointer to avoid repeated triplets
  • When sum == 0, record triplet and skip both left and right duplicates
  • Time: O(n²) — sort O(n log n) plus n iterations each calling O(n) two-pointer scan
15. What edge cases cause merge intervals to fail?

Expected answer points:

  • Empty intervals list — return empty immediately
  • Single interval — return it as-is
  • Non-overlapping intervals — each becomes separate merged interval
  • Fully contained intervals — keep the outer boundaries
  • Intervals with same start value — merge by taking max end
16. When would you choose DFS over BFS despite BFS finding shortest path?

Expected answer points:

  • When you need to find ANY path (not shortest) — DFS explores depth first
  • When memory is tight: BFS worst-case O(V) vs DFS O(V) but different distribution
  • For topological sort — only DFS-based approach works reliably
  • When solution is deep in the tree — BFS might explore many irrelevant nodes
17. How does the sliding window handle negative numbers in subarray sum problems?

Expected answer points:

  • Fixed-size sliding window still works — it only tracks sum algebraically
  • Variable-size window (max length subarray with sum < k) works — contraction triggers on constraint violation
  • Maximum subarray sum (Kadane's algorithm) doesn't use sliding window — needs dynamic programming
  • Key insight: negative numbers don't break the sliding mechanism — only the interpretation changes
18. What is the difference between detecting a cycle and finding its start in linked lists?

Expected answer points:

  • Detection: Floyd's algorithm with slow/fast pointers — O(1) space
  • Finding start: after detection, reset one pointer to head and move both 1 step — they meet at cycle start
  • Proof: distance from head to cycle start = distance from meeting point to cycle start
  • Common follow-up: finding cycle length — count steps from start node until you return
19. How do you handle an empty or single-element input in BFS?

Expected answer points:

  • Empty graph (no vertices): return empty result, queue initializes empty
  • Single vertex, no edges: return [start], visited set contains only that vertex
  • Edge case in code: while queue: loop naturally handles empty — body never executes
  • Always initialize visited with start node to prevent reprocessing
20. What happens when fast pointer reaches end of linked list in cycle detection?

Expected answer points:

  • Fast pointer reaches null (end) when no cycle exists — loop terminates returning false
  • Fast.next or fast.next.next being null indicates end of list
  • If cycle exists, fast pointer loops indefinitely and never reaches null
  • Important: fast must check fast and fast.next simultaneously — order matters

Further Reading

Conclusion

With these five patterns, you can handle most easy and medium difficulty problems. When you encounter a problem, ask whether the input is sorted (two pointers), about subarrays or substrings (sliding window), a linked list (fast-slow), intervals (merge), or shortest path (BFS). Combining patterns is common—BFS plus a hash map for visited tracking, or sliding window with a hash map for character counting. Understanding why each pattern works is more valuable than memorizing solutions.

Category

Related Posts

Amazon/Google/Microsoft Tag Problems: Interview Patterns

Learn which data structures, algorithms, and problem patterns Amazon, Google, and Microsoft interviewers favor—and how to prepare for each company's style.

#amazon #google #microsoft

Code Quality and Edge Cases in Technical Interviews

Learn how to write clean, maintainable code that impresses interviewers by handling edge cases, naming variables well, and organizing solutions modularly.

#coding-interview #code-quality #problem-solving

Binary Search Variants: Beyond Simple Lookup

Master variations of binary search including lower bound, upper bound, search in rotated array, and fractional searching for optimization problems.

#binary-search #algorithms #searching