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