All articles
Article

leetcode-patterns

Pattern recognition beats brute-force memorization. Candidates who grind 600 random LeetCode problems without organizing by pattern hit a plateau around proble…

10 min read

23 LeetCode Patterns That Cover 95% of FAANG Questions

Pattern recognition beats brute-force memorization. Candidates who grind 600 random LeetCode problems without organizing by pattern hit a plateau around problem 200. Problem-solving speed stops compounding because they're learning each problem as a one-off. Candidates who learn the 23 patterns in this guide solve novel variants faster, write cleaner code, and pass FAANG bars at much higher rates.

This is the hub pillar for pattern-based prep. Each of the 23 patterns gets a one-paragraph trigger description, a template snippet, and a link to the full pattern guide where applicable. Every spoke pillar (sliding window, DP, binary search, etc.) links back here as the parent.

Why patterns beat problems

The 2022 advice was "solve 200 LeetCode problems." That advice produced two cohorts. Candidates who happened to recognize each new problem as a variant of one they'd seen. Candidates who froze on every problem that wasn't an exact match. The first group passed FAANG loops. The second got the "we'll keep your resume on file."

Difference between the cohorts wasn't IQ or work ethic. The first group implicitly built a pattern map while solving. The 23 patterns in this guide make that pattern map explicit, so you don't have to discover it through 200 problems.

In 2026 this matters even more because AI tools make pure memorization worthless. The interviewer assumes you've seen every Blind 75 problem. The question is whether you can recognize the next variant.

The plateau hits at problem 200 if you grind randomly. Pattern fluency lets the next 100 problems compound on the first 100, instead of starting from zero each time.

TL;DR — the 23 patterns

For position-zero featured snippet:

  1. Two Pointers
  2. Sliding Window
  3. Fast & Slow Pointers
  4. Merge Intervals
  5. Cyclic Sort
  6. In-Place Linked List Reversal
  7. Tree BFS
  8. Tree DFS
  9. Two Heaps
  10. Subsets / Backtracking
  11. Modified Binary Search
  12. Bitwise XOR
  13. Top K Elements
  14. K-Way Merge
  15. 0/1 Knapsack DP
  16. Unbounded Knapsack DP
  17. Longest Subsequence DP
  18. Topological Sort
  19. Union-Find / DSU
  20. Trie
  21. Monotonic Stack
  22. Prefix Sum
  23. Bit Manipulation

Each is detailed below with trigger, template, and example problems.

Pattern 1: Two Pointers

Trigger: sorted array with pairs (LC 167), in-place removal (LC 26), palindrome check (LC 125), three-sum (LC 15).

Template: two indices left and right moving toward each other (or both forward, no shrink. That's two-pointers-same-direction, distinct from sliding window).

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

Companion: Two Pointers Pattern Guide.

Pattern 2: Sliding Window

Trigger: "longest substring", "minimum window", "maximum sum subarray of size K", "subarray with at most K distinct".

Template: two indices same direction with window-state aggregate (sum, count, frequency map).

def longest_at_most_k(s, k):
    freq = {}
    left = 0
    best = 0
    for right in range(len(s)):
        freq[s[right]] = freq.get(s[right], 0) + 1
        while len(freq) > k:
            freq[s[left]] -= 1
            if freq[s[left]] == 0:
                del freq[s[left]]
            left += 1
        best = max(best, right - left + 1)
    return best

Companion: Sliding Window Pattern Guide.

Pattern 3: Fast & Slow Pointers (Floyd's Tortoise and Hare)

Trigger: linked list cycle detection (LC 141), find middle of list (LC 876), happy number (LC 202).

Template: slow advances by 1, fast by 2. If they meet, there's a cycle.

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

Pattern 4: Merge Intervals

Trigger: "merge overlapping intervals" (LC 56), "insert interval" (LC 57), "meeting rooms" (LC 252, 253).

Template: sort by start. Iterate. Merge if current.start <= previous.end.

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

Pattern 5: Cyclic Sort

Trigger: array of integers in range [1, n] with duplicates or missing (LC 268, 287, 442, 448).

Template: swap each element to its correct index. O(n) time, O(1) extra space.

def find_missing(nums):
    i = 0
    while i < len(nums):
        correct = nums[i] - 1
        if 0 <= correct < len(nums) and nums[i] != nums[correct]:
            nums[i], nums[correct] = nums[correct], nums[i]
        else:
            i += 1
    for i, n in enumerate(nums):
        if n != i + 1:
            return i + 1

Pattern 6: In-Place Linked List Reversal

Trigger: reverse linked list (LC 206), reverse sublist (LC 92), reverse in groups of K (LC 25).

Template: prev/curr/next dance. Iterative is cleaner than recursive.

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

Pattern 7: Tree BFS

Trigger: "level order traversal" (LC 102), "right side view" (LC 199), "zigzag" (LC 103), shortest-path-in-tree (LC 111).

Template: queue, process level by level.

from collections import deque

def level_order(root):
    if not root:
        return []
    result = []
    queue = deque([root])
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.popleft()
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level)
    return result

Companion: BFS Pattern Guide.

Pattern 8: Tree DFS

Trigger: "path sum" (LC 112), "diameter of tree" (LC 543), "validate BST" (LC 98), "lowest common ancestor" (LC 236).

Template: recursion or explicit stack. Pre/in/post-order depending on problem.

def max_depth(root):
    if not root:
        return 0
    return 1 + max(max_depth(root.left), max_depth(root.right))

Companion: DFS Pattern Guide.

Pattern 9: Two Heaps

Trigger: "find median in stream" (LC 295), "sliding window median" (LC 480).

Template: max-heap for lower half, min-heap for upper half. Rebalance on every insert.

import heapq

class MedianFinder:
    def __init__(self):
        self.lo = []  # max-heap (negated)
        self.hi = []  # min-heap
    def addNum(self, num):
        heapq.heappush(self.lo, -num)
        heapq.heappush(self.hi, -heapq.heappop(self.lo))
        if len(self.hi) > len(self.lo):
            heapq.heappush(self.lo, -heapq.heappop(self.hi))
    def findMedian(self):
        if len(self.lo) > len(self.hi):
            return -self.lo[0]
        return (-self.lo[0] + self.hi[0]) / 2

Pattern 10: Subsets / Backtracking

Trigger: "all subsets" (LC 78), "permutations" (LC 46), "combination sum" (LC 39), "n-queens" (LC 51).

Template: recursive choose-or-skip, with backtracking on the recursion stack.

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

Trigger: sorted with twist (rotated, peak, 2D matrix), or "binary search on answer" (Koko, Capacity, Split Array).

Companion: Binary Search Pattern Guide.

Pattern 12: Bitwise XOR

Trigger: "single number" (LC 136), "missing number" (LC 268), find two non-duplicates.

Template: XOR all elements. Cancellation property gives the answer.

def single_number(nums):
    result = 0
    for n in nums:
        result ^= n
    return result

Pattern 13: Top K Elements

Trigger: "top K frequent" (LC 347), "K closest points" (LC 973), "kth largest" (LC 215).

Template: min-heap of size K. Push, then pop when size > K.

import heapq

def top_k_frequent(nums, k):
    from collections import Counter
    freq = Counter(nums)
    heap = []
    for n, c in freq.items():
        heapq.heappush(heap, (c, n))
        if len(heap) > k:
            heapq.heappop(heap)
    return [n for _, n in heap]

Pattern 14: K-Way Merge

Trigger: "merge K sorted lists" (LC 23), "smallest range covering K lists" (LC 632).

Template: min-heap with one element from each list. Pop, advance, push.

import heapq

def merge_k_lists(lists):
    heap = []
    for i, lst in enumerate(lists):
        if lst:
            heapq.heappush(heap, (lst.val, i, lst))
    dummy = ListNode()
    curr = dummy
    while heap:
        val, i, node = heapq.heappop(heap)
        curr.next = node
        curr = curr.next
        if node.next:
            heapq.heappush(heap, (node.next.val, i, node.next))
    return dummy.next

Pattern 15: 0/1 Knapsack DP

Trigger: "can we hit a target sum" (LC 416), "target sum" (LC 494), 2D knapsack (LC 474).

Companion: DP Patterns Guide.

Pattern 16: Unbounded Knapsack DP

Trigger: "minimum coins" (LC 322), "number of ways" (LC 518), "combination sum IV" (LC 377).

Companion: DP Patterns Guide.

Pattern 17: Longest Subsequence DP

Trigger: "longest common subsequence" (LC 1143), "edit distance" (LC 72), "longest increasing subsequence" (LC 300).

Companion: DP Patterns Guide.

Pattern 18: Topological Sort

Trigger: "course schedule" (LC 207, 210), "alien dictionary" (LC 269), "minimum height tree" (LC 310).

Template: Kahn's algorithm with in-degree count + BFS queue, OR DFS with post-order.

from collections import defaultdict, deque

def topo_sort(num_nodes, edges):
    graph = defaultdict(list)
    in_degree = [0] * num_nodes
    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1
    queue = deque(i for i in range(num_nodes) if in_degree[i] == 0)
    result = []
    while queue:
        node = queue.popleft()
        result.append(node)
        for neighbor in graph[node]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)
    return result if len(result) == num_nodes else []

Companion: Topological Sort Pattern Guide.

Pattern 19: Union-Find / Disjoint Set Union (DSU)

Trigger: "number of connected components" (LC 323), "redundant connection" (LC 684), "accounts merge" (LC 721).

Template: parent array + path compression + union by rank.

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, x, y):
        rx, ry = self.find(x), self.find(y)
        if rx == ry:
            return False
        if self.rank[rx] < self.rank[ry]:
            self.parent[rx] = ry
        elif self.rank[rx] > self.rank[ry]:
            self.parent[ry] = rx
        else:
            self.parent[ry] = rx
            self.rank[rx] += 1
        return True

Pattern 20: Trie

Trigger: "prefix tree" (LC 208), "word search II" (LC 212), autocomplete, "longest common prefix" with many words.

class Trie:
    def __init__(self):
        self.children = {}
        self.is_end = False
    def insert(self, word):
        node = self
        for c in word:
            if c not in node.children:
                node.children[c] = Trie()
            node = node.children[c]
        node.is_end = True
    def search(self, word):
        node = self
        for c in word:
            if c not in node.children:
                return False
            node = node.children[c]
        return node.is_end

Pattern 21: Monotonic Stack

Trigger: "next greater element" (LC 496), "daily temperatures" (LC 739), "largest rectangle in histogram" (LC 84), "trapping rain water" (LC 42).

Template: stack maintains monotonic order. Pop on violation.

def daily_temperatures(temperatures):
    result = [0] * len(temperatures)
    stack = []
    for i, t in enumerate(temperatures):
        while stack and temperatures[stack[-1]] < t:
            j = stack.pop()
            result[j] = i - j
        stack.append(i)
    return result

Companion: Monotonic Stack Pattern Guide.

Pattern 22: Prefix Sum

Trigger: "subarray sum equals K" (LC 560), "range sum query" (LC 303), "continuous subarray sum" (LC 523).

Template: prefix sum array + hashmap of prefix sums seen.

def subarray_sum(nums, k):
    prefix = {0: 1}
    cur = count = 0
    for n in nums:
        cur += n
        count += prefix.get(cur - k, 0)
        prefix[cur] = prefix.get(cur, 0) + 1
    return count

Pattern 23: Bit Manipulation

Trigger: "count set bits" (LC 191), "reverse bits" (LC 190), "power of two" (LC 231).

def count_bits(n):
    count = 0
    while n:
        n &= n - 1  # clears lowest set bit
        count += 1
    return count

Pattern recognition flowchart

For any new problem, ask in order:

  1. Sorted array + pair/triplet question? → Two Pointers (Pattern 1).
  2. Subarray/substring with constraint? → Sliding Window (Pattern 2).
  3. Linked list with cycle/middle/intersection? → Fast & Slow Pointers (Pattern 3).
  4. Overlapping ranges? → Merge Intervals (Pattern 4).
  5. Sorted-range integers in array? → Cyclic Sort (Pattern 5).
  6. Linked list reversal? → Pattern 6.
  7. Tree level-by-level? → Tree BFS (Pattern 7).
  8. Tree path / depth? → Tree DFS (Pattern 8).
  9. Median in stream? → Two Heaps (Pattern 9).
  10. All combinations / permutations? → Backtracking (Pattern 10).
  11. Sorted with twist OR "minimum X such that"? → Modified Binary Search (Pattern 11).
  12. Find single different element? → Bitwise XOR (Pattern 12).
  13. Top/Kth element? → Top K (Pattern 13) or K-Way Merge (Pattern 14).
  14. Optimal sub-result with overlap? → Knapsack/LCS DP (Patterns 15-17).
  15. Dependency ordering? → Topological Sort (Pattern 18).
  16. Connected components / cycle detection in graph? → Union-Find (Pattern 19).
  17. Prefix / autocomplete? → Trie (Pattern 20).
  18. Next greater / smaller? → Monotonic Stack (Pattern 21).
  19. Subarray sum equals X? → Prefix Sum (Pattern 22).
  20. Bit-level operations? → Bit Manipulation (Pattern 23).

How to use this guide

Two-month plan: one week per pattern (or two weeks for the harder DP patterns). Solve 4-6 problems per pattern.

After two months you should have solved roughly 100 problems across all patterns. Compare to grinding 600 random problems with no organization. The pattern-grouped 100 produces much better recognition speed.

2026 FAANG expectations

Interviewers in 2026 expect:

  • Pattern recognition in under 90 seconds for any problem.
  • Template muscle memory for the top 10 patterns (write the skeleton in under 5 minutes).
  • Comfort articulating WHY a pattern fits ("this is sliding window because we need a window-state aggregate that grows or shrinks based on the constraint").

For the 2026 interview shifts that drive these expectations, see What Changed in FAANG Interviews After ChatGPT.

FAQ

Are these the only patterns I need? About 95% of FAANG questions reduce to these 23. The remaining 5% are advanced (segment trees, Fenwick trees, suffix arrays) and come up only at L6+ or specialized teams.

How do these patterns relate to Blind 75 or NeetCode 150? Blind 75 is a problem list. NeetCode 150 is a problem list organized loosely by pattern. This is the pattern list itself. Use the patterns to navigate either problem list.

Should I memorize all 23 templates? Yes for the top 10. The next 13 should be writeable from a high-level sketch, even if you'd need to look up syntax details.

What's the most common pattern at FAANG? Tree DFS, Sliding Window, and Modified Binary Search are the top three by frequency in our 2026 internal Discord-tracked dataset across 800+ interview reports.

The verdict

The 23 patterns cover roughly 95% of FAANG interview questions in 2026. Mastering the patterns beats grinding random problems by a wide margin. The pillar guides linked throughout (Sliding Window, DP, Binary Search, etc.) take you from recognition to mastery.

If you found this useful, FaangCoder helps candidates iterate to optimal solutions in real interviews. That includes spot-recognition of which pattern fits an unfamiliar problem. $399 lifetime ($199/mo monthly option). See the Solve demo, or join the Discord to talk to other candidates working through the patterns.

FaangCoder

Iterate to the optimal solution. In three keystrokes.

FaangCoder reads your problem, code, and terminal directly from memory. No screenshots, no waiting. Solve, Debug, and Optimize iteratively until the answer is right.