The 15 LeetCode Patterns That Cover 90% of Coding Interviews

Engineers and former hiring managers from FAANG-tier companies. Combined 500+ technical interviews conducted and 1,200+ hours of coaching candidates.

Grinding 500 LeetCode problems is the slow way. The fast way is to recognize that the vast majority of "interesting" coding interview problems are re-skins of about 15 underlying patterns. Master the patterns, and you'll walk into interviews recognizing the shape of each problem in the first 60 seconds — which is what your interviewer is actually scoring.

This guide gives you each pattern's: signal-words to recognize it, a clean template you can write from memory, complexity analysis, and the LeetCode problems that best exemplify it. When you can do one representative problem from each pattern cleanly, you're interview-ready. (Already past coding rounds and prepping for the next stage? See our 14-concept system design cheat sheet and how to pass the Amazon behavioral interview.)

Prerequisite: comfort with arrays, hash maps, linked lists, and basic recursion. This guide is for mid-to-senior-level interview prep, not "how do I start LeetCode."

How to Use This Guide

  1. Skim all 15 patterns once, in order.
  2. For each pattern, solve the 2 "canonical" problems listed — without looking at the template until you've tried on your own for 25 minutes.
  3. Then read the template, re-solve cleanly.
  4. Solve 1–2 more problems from the "practice" list per pattern. That's your minimum — more is fine, less is risky.
  5. Spaced review: re-do one problem from each pattern every 5–7 days.

Total volume: ~45–60 problems. Versus 500. That's the leverage.

1. Two Pointers

O(n) timeO(1) spaceArrays / Strings

Signal words: "sorted array," "find a pair," "palindrome," "remove duplicates in place."

Core idea: two indices moving toward/with each other, eliminating the need for nested loops.

def two_pointers(arr, target):
    left, right = 0, len(arr) - 1
    while left < right:
        s = arr[left] + arr[right]
        if s == target: return [left, right]
        if s < target: left += 1
        else: right -= 1
    return []

Canonical: Two Sum II (LC 167), Valid Palindrome (LC 125). Practice: 3Sum (LC 15), Container With Most Water (LC 11), Trapping Rain Water (LC 42).

2. Sliding Window

O(n) timeO(k) spaceArrays / Strings

Signal words: "substring / subarray with," "maximum / minimum of size K," "longest / shortest window."

def sliding_window(s, k):
    left = 0
    result = 0
    state = {}  # or counter, sum, etc.
    for right in range(len(s)):
        # expand window
        state[s[right]] = state.get(s[right], 0) + 1
        # shrink while invalid
        while window_invalid(state):
            state[s[left]] -= 1
            if state[s[left]] == 0: del state[s[left]]
            left += 1
        result = max(result, right - left + 1)
    return result

Canonical: Longest Substring Without Repeating Characters (LC 3), Minimum Size Subarray Sum (LC 209). Practice: Longest Repeating Character Replacement (LC 424), Minimum Window Substring (LC 76), Permutation in String (LC 567).

3. Fast & Slow Pointers (Floyd's Cycle Detection)

O(n) timeO(1) spaceLinked Lists / Cycles

Signal words: "linked list cycle," "find middle," "happy number," "duplicate number (Floyd's)."

def has_cycle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow is fast: return True
    return False

Canonical: Linked List Cycle (LC 141), Middle of the Linked List (LC 876). Practice: Linked List Cycle II (LC 142), Find the Duplicate Number (LC 287), Happy Number (LC 202).

4. Merge Intervals

O(n log n) timeO(n) spaceArrays / Scheduling

Signal words: "intervals," "meeting rooms," "overlap," "insert into," "busy schedule."

def merge(intervals):
    intervals.sort(key=lambda x: x[0])
    out = [intervals[0]]
    for start, end in intervals[1:]:
        if start <= out[-1][1]:
            out[-1][1] = max(out[-1][1], end)
        else:
            out.append([start, end])
    return out

Canonical: Merge Intervals (LC 56), Insert Interval (LC 57). Practice: Meeting Rooms II (LC 253), Non-overlapping Intervals (LC 435).

5. Cyclic Sort

O(n) timeO(1) spaceArrays 1..N

Signal words: "array of integers 1 to N," "find missing / duplicate numbers," "no extra space."

def cyclic_sort(nums):
    i = 0
    while i < len(nums):
        correct = nums[i] - 1
        if nums[i] != nums[correct]:
            nums[i], nums[correct] = nums[correct], nums[i]
        else:
            i += 1
    return nums

Canonical: Missing Number (LC 268), Find All Numbers Disappeared in an Array (LC 448). Practice: First Missing Positive (LC 41), Find the Duplicate Number (LC 287).

6. Reversal of a Linked List (In-place)

O(n) timeO(1) spaceLinked Lists

Signal words: "reverse linked list," "reverse sublist," "rotate linked list."

def reverse(head):
    prev = None
    curr = head
    while curr:
        nxt = curr.next
        curr.next = prev
        prev = curr
        curr = nxt
    return prev

Canonical: Reverse Linked List (LC 206), Reverse Linked List II (LC 92). Practice: Reverse Nodes in k-Group (LC 25), Rotate List (LC 61).

7. BFS (Tree / Graph Level-Order)

O(V+E) timeO(V) spaceTrees / Graphs

Signal words: "level-order," "shortest path in unweighted graph," "minimum steps to reach," "word ladder."

from collections import deque
def bfs(root):
    if not root: return []
    q = deque([root])
    result = []
    while q:
        level = []
        for _ in range(len(q)):
            node = q.popleft()
            level.append(node.val)
            if node.left: q.append(node.left)
            if node.right: q.append(node.right)
        result.append(level)
    return result

Canonical: Binary Tree Level Order Traversal (LC 102), Word Ladder (LC 127). Practice: Rotting Oranges (LC 994), 01 Matrix (LC 542), Shortest Path in Binary Matrix (LC 1091).

8. DFS (Tree / Graph Recursion + Backtracking)

O(V+E) timeO(V) spaceTrees / Graphs

Signal words: "all paths," "does a path exist," "subsets," "permutations," "combinations," "generate all."

def dfs(node, path, result):
    if not node: return
    path.append(node.val)
    if is_leaf(node):
        result.append(list(path))
    dfs(node.left, path, result)
    dfs(node.right, path, result)
    path.pop()  # backtrack

Canonical: Path Sum II (LC 113), Subsets (LC 78), Permutations (LC 46). Practice: Combination Sum (LC 39), Word Search (LC 79), N-Queens (LC 51).

9. Two Heaps

O(log n) insertO(n) spaceRunning Median

Signal words: "median of a stream," "find the middle of," "schedule tasks by priority."

import heapq
class MedianFinder:
    def __init__(self):
        self.low = []   # max-heap (negate)
        self.high = []  # min-heap
    def add(self, n):
        heapq.heappush(self.low, -n)
        heapq.heappush(self.high, -heapq.heappop(self.low))
        if len(self.high) > len(self.low):
            heapq.heappush(self.low, -heapq.heappop(self.high))
    def median(self):
        if len(self.low) > len(self.high): return -self.low[0]
        return (-self.low[0] + self.high[0]) / 2

Canonical: Find Median from Data Stream (LC 295). Practice: Sliding Window Median (LC 480), IPO (LC 502).

10. Subsets / Combinations (Backtracking)

O(2^n) or O(n!)O(n) spaceEnumeration

Signal words: "all subsets," "all combinations," "generate strings of N," "powerset."

def subsets(nums):
    result = []
    def backtrack(start, path):
        result.append(list(path))
        for i in range(start, len(nums)):
            path.append(nums[i])
            backtrack(i + 1, path)
            path.pop()
    backtrack(0, [])
    return result

Canonical: Subsets (LC 78), Permutations (LC 46). Practice: Letter Combinations of a Phone Number (LC 17), Palindrome Partitioning (LC 131), Generate Parentheses (LC 22).

11. Modified Binary Search

O(log n) timeO(1) spaceSorted / Monotonic

Signal words: "sorted array," "rotated," "find first / last occurrence," "capacity / threshold to make X work."

def binary_search(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if arr[mid] == target: return mid
        if arr[mid] < target: lo = mid + 1
        else: hi = mid - 1
    return -1

Canonical: Binary Search (LC 704), Search in Rotated Sorted Array (LC 33). Practice: Find First and Last Position (LC 34), Koko Eating Bananas (LC 875), Median of Two Sorted Arrays (LC 4).

12. Top-K Elements (Heap)

O(n log k) timeO(k) spaceHeaps

Signal words: "top K," "kth largest / smallest," "most frequent," "closest points."

import heapq
def top_k(nums, k):
    return heapq.nlargest(k, nums)
# or manually, for O(n log k) with a min-heap:
def top_k_manual(nums, k):
    h = []
    for n in nums:
        heapq.heappush(h, n)
        if len(h) > k:
            heapq.heappop(h)
    return h

Canonical: Kth Largest Element (LC 215), Top K Frequent Elements (LC 347). Practice: K Closest Points to Origin (LC 973), Find K Closest Elements (LC 658), Merge k Sorted Lists (LC 23).

13. Topological Sort

O(V+E) timeO(V) spaceDAGs / Ordering

Signal words: "course schedule," "dependency order," "build order," "task scheduling with prerequisites."

from collections import deque, defaultdict
def topo_sort(n, edges):
    graph = defaultdict(list)
    in_deg = [0] * n
    for u, v in edges:
        graph[u].append(v)
        in_deg[v] += 1
    q = deque(i for i in range(n) if in_deg[i] == 0)
    order = []
    while q:
        node = q.popleft()
        order.append(node)
        for nxt in graph[node]:
            in_deg[nxt] -= 1
            if in_deg[nxt] == 0: q.append(nxt)
    return order if len(order) == n else []

Canonical: Course Schedule (LC 207), Course Schedule II (LC 210). Practice: Alien Dictionary (LC 269), Minimum Height Trees (LC 310).

14. Dynamic Programming

variesvariesOptimization / Counting

Signal words: "maximum / minimum," "count the ways," "can you reach," "longest / shortest," "substructure."

This is really ~5 sub-patterns (1D DP, 2D DP, interval DP, DP on trees, bitmask DP) but the top-down template applies to most:

from functools import cache
def dp_problem(args):
    @cache
    def solve(state):
        if base_case(state): return base_value
        return combine(solve(next_state1), solve(next_state2))
    return solve(initial_state)

Canonical: Climbing Stairs (LC 70), House Robber (LC 198), Longest Common Subsequence (LC 1143). Practice: Coin Change (LC 322), Longest Increasing Subsequence (LC 300), Edit Distance (LC 72), Word Break (LC 139), Partition Equal Subset Sum (LC 416).

15. Union-Find (Disjoint Set)

O(α(n)) per opO(n) spaceGraph Connectivity

Signal words: "connected components," "is there a path between X and Y," "redundant connection," "accounts merge."

class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n
    def find(self, x):
        while self.parent[x] != x:
            self.parent[x] = self.parent[self.parent[x]]  # path compression
            x = self.parent[x]
        return x
    def union(self, a, b):
        ra, rb = self.find(a), self.find(b)
        if ra == rb: return False
        if self.rank[ra] < self.rank[rb]: ra, rb = rb, ra
        self.parent[rb] = ra
        if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        return True

Canonical: Number of Islands (LC 200) — DFS solution works too, but UF is cleaner. Redundant Connection (LC 684). Practice: Accounts Merge (LC 721), Number of Connected Components (LC 323), Most Stones Removed (LC 947).

The 90/10 Rule

The above 15 patterns will carry you through roughly 90% of mid-level coding interviews. The remaining 10% covers:

Pattern-Recognition Workflow During the Interview

This is the mental checklist that takes you from "I don't know this problem" to "I know the pattern" in 60 seconds:

  1. Input type? Sorted array → binary search / two pointers. Linked list → fast/slow pointers. Graph → BFS/DFS/UF/Topo. Intervals → merge intervals.
  2. Output type? "All possible…" → backtracking. "Top K" → heap. "Count the ways" → DP. "Shortest path" → BFS (unweighted) or Dijkstra (weighted).
  3. Constraint hint. N ≤ 20 → backtracking / bitmask DP. N ≤ 100 → O(n³) DP. N ≤ 10⁴ → O(n²). N ≤ 10⁶ → O(n log n) or O(n). N ≤ 10¹⁸ → O(log n).
  4. Sub-problem repetition? Overlapping sub-problems → DP. Unique sub-problems → divide & conquer or backtracking.

Practice these patterns with AI feedback

CoPilot Interview's coding mode lets you paste a problem (or screenshot it from LeetCode), get a pattern-aware explanation with a clean template, full Big-O analysis, and follow-up questions — so you internalize the pattern, not just memorize the answer.

Try Coding Mode Free →

FAQ

How long does it take to master these 15 patterns?

If you can code fluently, ~60–100 hours (6–8 weeks at 10 hr/week). If you're rusty, double that. Don't try to cram in 2 weeks — spaced repetition is what makes the patterns stick.

Should I memorize these templates?

Not word-for-word, but you should be able to write a working template for any pattern from scratch in < 3 minutes. The act of re-deriving the template each time is what cements the pattern.

What about the problems Meta, Google, and Amazon tag as their "top 50"?

Do them after the patterns. Most are either multiple patterns combined or a twist on a canonical problem. Working through a company's top-50 without pattern knowledge = memorization. Working through it with pattern knowledge = pattern recognition practice.

Do I need to know data structures like B-trees, red-black trees?

No. For coding rounds, assume built-in ordered structures (Python's SortedList, Java's TreeMap). You'll never implement a red-black tree in a 45-minute interview.

What's the fastest way from zero to interview-ready?

Minimum viable path: Two Pointers → Sliding Window → DFS/BFS → Binary Search → Heap → DP. These six cover ~70% of interview questions. Hit these first, expand from there.

Related Resources
Coding Interview Help
Real-time AI for technical rounds.
System Design Cheat Sheet
14 concepts for FAANG senior rounds.
AI Interview Assistant
Real-time AI in coding interviews.
System Design Interview Tool
AI-powered architecture round prep.
Ghost Mode
Invisible during screen-share.
vs Final Round AI
Comparison of AI interview tools.