Coding Interview Patterns: The Complete Guide (2026)
Coding interview patterns are the fastest way to go from LeetCode grind to confident problem-solver. If you’ve ever stared at a problem with no idea where to start, you’re not alone. Most candidates grind hundreds of problems and still freeze in real interviews because they’re memorizing solutions instead of learning patterns.
The truth is, coding interview problems are not random. They follow a small set of recurring patterns. Once you recognize those patterns, you stop solving problems one by one and start solving categories of problems. That’s the difference between a candidate who scrapes by and one who confidently walks through a Google interview.
This guide covers the 15 most important coding interview patterns in 2026 with explanations, recognition tips, Python templates, and example problems for each. Bookmark it. Come back to it. Then go practice coding interview patterns on Intervu.
Why Coding Interview Problems Follow Patterns
Companies like Google, Meta, and Amazon aren’t trying to trick you with unique puzzles. They’re testing whether you can recognize the structure of a problem and apply a known strategy.
You don’t calculate from scratch every game; you recognize the board state and apply a framework. Coding interviews work the same way.
The moment you see “find the maximum sum subarray of size K,” you should think Sliding Window. When you see “detect a cycle in a linked list,” you should think Fast & Slow Pointers. That pattern-recognition reflex is what separates prepared candidates from everyone else.
1. Two Pointers
Pattern Explanation
Two Pointers uses two index variables that move through an array (or string), usually toward each other from opposite ends, or both moving forward at different speeds.
When to Recognize It
- The input is a sorted array or string
- You need to find a pair (or triplet) that satisfies a condition
- The problem asks you to do something in-place with O(1) extra space
Key phrases: “find two numbers that sum to target”, “remove duplicates in-place”, “reverse a string”
Python Template
def two_pointers(arr, target):
left, right = 0, len(arr) - 1
while left < right:
current_sum = arr[left] + arr[right]
if current_sum == target:
return [left, right]
elif current_sum < target:
left += 1
else:
right -= 1
return []
Example Problems
- Two Sum II (LeetCode #167). Sorted array, find pair that sums to target. · Practice →
- 3Sum (LeetCode #15). Extend to triplets. · Practice →
- Container With Most Water (LeetCode #11) · Practice →
- Valid Palindrome (LeetCode #125) · Practice →
2. Sliding Window
Pattern Explanation
Sliding Window maintains a “window” (subarray or substring) that expands and contracts as it moves through the input. It avoids recomputing the entire window from scratch each time by only adjusting the window’s boundaries.
When to Recognize It
- The problem involves a contiguous subarray or substring
- You’re asked for a maximum, minimum, or specific condition over a subarray
- A brute force O(n²) solution exists but you need O(n)
Key phrases: “longest substring without repeating characters”, “maximum sum subarray of size k”, “minimum window substring”
Python Template
def sliding_window(arr, k):
window_sum = sum(arr[:k])
max_sum = window_sum
for i in range(k, len(arr)):
window_sum += arr[i] - arr[i - k] # slide: add right, remove left
max_sum = max(max_sum, window_sum)
return max_sum
Example Problems
- Maximum Average Subarray I (LeetCode #643) · Practice →
- Longest Substring Without Repeating Characters (LeetCode #3) · Practice →
- Minimum Window Substring (LeetCode #76) · Practice →
- Fruit Into Baskets (LeetCode #904) · Practice →
3. Prefix Sum
Pattern Explanation
Prefix Sum precomputes cumulative sums of an array so that any subarray sum can be calculated in O(1) time. Combined with a hash map, it’s powerful for finding subarrays with a target sum.
When to Recognize It
- You need the sum of a subarray repeatedly
- The problem asks for subarrays with a specific sum
- You’re working with range queries
Key phrases: “subarray sum equals K”, “number of subarrays with sum”, “range sum query”
Python Template
def subarray_sum(nums, k):
count = 0
prefix_sum = 0
seen = {0: 1} # prefix_sum -> frequency
for num in nums:
prefix_sum += num
# if (prefix_sum - k) was seen before, a valid subarray exists
count += seen.get(prefix_sum - k, 0)
seen[prefix_sum] = seen.get(prefix_sum, 0) + 1
return count
Example Problems
- Subarray Sum Equals K (LeetCode #560) · Practice →
- Range Sum Query - Immutable (LeetCode #303) · Practice →
- Product of Array Except Self (LeetCode #238) · Practice → (solved with prefix/suffix products — a cousin of the prefix sum idea)
- Continuous Subarray Sum (LeetCode #523) · Practice →
4. Fast & Slow Pointers
Pattern Explanation
Also called the tortoise and hare algorithm. Two pointers move through a linked list (or array) at different speeds. Typically one moves one step at a time, and the other moves two steps. This creates a predictable meeting point when a cycle exists.
When to Recognize It
- The problem involves a linked list
- You need to detect a cycle
- You need to find the middle of a linked list
- You need to find the start of a cycle
Python Template
def has_cycle(head):
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True # cycle detected
return False
Example Problems
- Linked List Cycle (LeetCode #141) · Practice →
- Linked List Cycle II (LeetCode #142). Find the start. · Practice →
- Middle of the Linked List (LeetCode #876) · Practice →
- Happy Number (LeetCode #202) · Practice →
5. Binary Search
Pattern Explanation
Binary Search eliminates half the search space with every comparison. It runs in O(log n) and applies far beyond “search a sorted array” since you can binary search on the answer space itself.
When to Recognize It
- The input is sorted, or the answer exists within a monotonic range
- You need to find a specific value, boundary, or threshold
- A linear scan would work but O(log n) is expected
Key phrases: “find the minimum/maximum value that satisfies a condition”, “search in rotated sorted array”
Python Template
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = left + (right - left) // 2 # avoids overflow
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Example Problems
- Binary Search (LeetCode #704) · Practice →
- Find Minimum in Rotated Sorted Array (LeetCode #153) · Practice →
- Search in Rotated Sorted Array (LeetCode #33) · Practice →
- Koko Eating Bananas (LeetCode #875). Binary search on answer. · Practice →
6. BFS (Breadth-First Search)
Pattern Explanation
BFS explores a graph or tree level by level using a queue. It’s the go-to algorithm for shortest path problems in unweighted graphs and for level-order traversal.
When to Recognize It
- You need the shortest path between two nodes
- You’re asked for level-order or layer-by-layer traversal
- You’re exploring states in a grid or graph and need the minimum number of steps
Python Template
from collections import deque
def bfs(graph, start):
visited = set([start])
queue = deque([start])
while queue:
node = queue.popleft()
for neighbor in graph[node]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
Example Problems
- Binary Tree Level Order Traversal (LeetCode #102) · Practice →
- Rotting Oranges (LeetCode #994) · Practice →
- Word Ladder (LeetCode #127) · Practice →
- Number of Islands (LeetCode #200). Can use BFS or DFS. · Practice →
7. DFS (Depth-First Search)
Pattern Explanation
DFS explores as far as possible down one path before backtracking. It’s implemented with a stack (or recursion) and is ideal for exhaustive searches, path finding, and tree problems.
When to Recognize It
- You need to explore all paths or all combinations
- The problem involves a tree and asks about paths, depth, or subtrees
- You’re searching a graph for connectivity or components
Python Template
def dfs(graph, node, visited=None):
if visited is None:
visited = set()
visited.add(node)
for neighbor in graph[node]:
if neighbor not in visited:
dfs(graph, neighbor, visited)
return visited
Example Problems
- Number of Islands (LeetCode #200) · Practice →
- Max Area of Island (LeetCode #695) · Practice →
- Path Sum (LeetCode #112) · Practice →
- Clone Graph (LeetCode #133) · Practice →
8. Topological Sort
Pattern Explanation
Topological Sort orders the nodes of a directed acyclic graph (DAG) such that every directed edge goes from an earlier node to a later one. It’s used when tasks have dependencies.
When to Recognize It
- The problem involves tasks with prerequisites or ordering constraints
- The input is a directed graph and you need a linear ordering
- You need to detect a cycle in a directed graph
Key phrases: “course schedule”, “build order”, “task dependencies”
Python Template
from collections import deque
def topological_sort(vertices, edges):
in_degree = {v: 0 for v in range(vertices)}
graph = {v: [] for v in range(vertices)}
for u, v in edges:
graph[u].append(v)
in_degree[v] += 1
queue = deque([v for v in in_degree if in_degree[v] == 0])
order = []
while queue:
node = queue.popleft()
order.append(node)
for neighbor in graph[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
return order if len(order) == vertices else [] # empty = cycle detected
Example Problems
- Course Schedule (LeetCode #207) · Practice →
- Course Schedule II (LeetCode #210) · Practice →
- Alien Dictionary (LeetCode #269) · Practice →
- Minimum Height Trees (LeetCode #310) · Practice → (uses iterative leaf-trimming on an undirected graph — conceptually Kahn-style but not a strict DAG problem)
9. Union Find (Disjoint Set)
Pattern Explanation
Union Find (also called Disjoint Set Union) tracks which elements belong to the same connected component. It supports two operations: find (which group does this belong to?) and union (merge two groups).
When to Recognize It
- You need to dynamically track connected components
- The problem asks whether two nodes are in the same group
- You’re detecting cycles in an undirected graph
Key phrases: “number of connected components”, “detect cycle in undirected graph”, “redundant connection”
Python Template
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # path compression
return self.parent[x]
def union(self, x, y):
px, py = self.find(x), self.find(y)
if px == py:
return False # already connected
if self.rank[px] < self.rank[py]:
px, py = py, px
self.parent[py] = px
if self.rank[px] == self.rank[py]:
self.rank[px] += 1
return True
Example Problems
- Number of Connected Components in an Undirected Graph (LeetCode #323)
- Redundant Connection (LeetCode #684) · Practice →
- Accounts Merge (LeetCode #721) · Practice →
- Graph Valid Tree (LeetCode #261) · Practice →
10. Heap / Priority Queue
Pattern Explanation
A heap is a specialized tree that always gives you the minimum (min-heap) or maximum (max-heap) element in O(1), with insertion and deletion in O(log n). In Python, heapq implements a min-heap.
When to Recognize It
- You need the top K elements (largest, smallest, most frequent)
- You need to repeatedly extract the minimum or maximum
- The problem involves a stream of data and running statistics
Key phrases: “K largest elements”, “K closest points”, “merge K sorted lists”
Python Template
import heapq
# Min-heap (default in Python)
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
smallest = heapq.heappop(heap) # returns 1
# For max-heap: negate values
heapq.heappush(heap, -value)
largest = -heapq.heappop(heap)
Example Problems
- Kth Largest Element in an Array (LeetCode #215) · Practice →
- K Closest Points to Origin (LeetCode #973) · Practice →
- Merge K Sorted Lists (LeetCode #23) · Practice →
- Find Median from Data Stream (LeetCode #295) · Practice →
11. Dynamic Programming
Pattern Explanation
Dynamic Programming (DP) breaks a problem into overlapping subproblems, solves each once, and stores the result (memoization or tabulation). It applies when a problem has optimal substructure and overlapping subproblems.
When to Recognize It
- The problem asks for the number of ways, maximum, minimum, or whether something is possible
- Decisions at each step affect future choices
- A recursive solution would repeat the same subproblems
Key phrases: “how many ways”, “minimum cost”, “longest subsequence”, “can you reach”
Python Template
# Bottom-up tabulation example: Fibonacci
def dp_fib(n):
if n <= 1:
return n
dp = [0] * (n + 1)
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]
return dp[n]
Example Problems
- Climbing Stairs (LeetCode #70). Great starter. · Practice →
- House Robber (LeetCode #198) · Practice →
- Longest Common Subsequence (LeetCode #1143) · Practice →
- Coin Change (LeetCode #322) · Practice →
- 0/1 Knapsack. Classic DP archetype.
12. Backtracking
Pattern Explanation
Backtracking is a DFS-based technique for building solutions incrementally and abandoning (“pruning”) paths as soon as they’re determined to be invalid. It’s the foundation of constraint-solving problems.
When to Recognize It
- You need to find all combinations, permutations, or subsets
- The problem asks you to build solutions step by step with constraints
- You need to explore a decision tree and prune dead ends early
Key phrases: “generate all subsets”, “find all permutations”, “word search”, “N-Queens”
Python Template
def backtrack(result, current, start, nums):
result.append(list(current)) # record current state
for i in range(start, len(nums)):
current.append(nums[i]) # choose
backtrack(result, current, i + 1, nums) # explore
current.pop() # un-choose (backtrack)
def subsets(nums):
result = []
backtrack(result, [], 0, nums)
return result
Example Problems
- Subsets (LeetCode #78) · Practice →
- Permutations (LeetCode #46) · Practice →
- Combination Sum (LeetCode #39) · Practice →
- Word Search (LeetCode #79) · Practice →
- N-Queens (LeetCode #51)
13. Merge Intervals
Pattern Explanation
Merge Intervals deals with overlapping ranges. The key insight is always the same: sort by start time, then walk through and merge any interval that overlaps with the previous one by comparing boundaries.
When to Recognize It
- The input is a list of intervals or ranges
- You need to merge overlapping intervals or find gaps between them
- The problem involves scheduling, meetings, or time ranges
Key phrases: “meeting rooms”, “merge overlapping intervals”, “insert interval”, “employee free time”
Python Template
def merge_intervals(intervals):
if not intervals: return []
intervals.sort(key=lambda x: x[0]) # sort by start time
merged = [intervals[0]]
for start, end in intervals[1:]:
last_end = merged[-1][1]
if start <= last_end:
merged[-1][1] = max(last_end, end) # overlap: extend
else:
merged.append([start, end]) # no overlap: add new
return merged
Example Problems
- Merge Intervals (LeetCode #56) · Practice →
- Insert Interval (LeetCode #57) · Practice →
- Meeting Rooms II (LeetCode #253). Minimum number of rooms needed. · Practice →
- Employee Free Time (LeetCode #759)
14. Monotonic Stack
Pattern Explanation
A Monotonic Stack is a stack that maintains elements in strictly increasing or decreasing order. When a new element violates the order, you pop until it doesn’t — and those pops are where the useful work happens (finding the next greater/smaller element).
When to Recognize It
- You need the next greater or next smaller element for each item
- The problem involves spans, temperatures, or stock prices
- You need the largest rectangle or trapped water in a histogram-style problem
Key phrases: “next greater element”, “daily temperatures”, “largest rectangle in histogram”, “trapping rain water”
Python Template
def next_greater_element(nums):
result = [-1] * len(nums)
stack = [] # stores indices, maintains decreasing order of values
for i, num in enumerate(nums):
# pop all elements smaller than current — current is their next greater
while stack and nums[stack[-1]] < num:
idx = stack.pop()
result[idx] = num
stack.append(i)
return result
Example Problems
- Daily Temperatures (LeetCode #739) · Practice →
- Next Greater Element I (LeetCode #496)
- Largest Rectangle in Histogram (LeetCode #84) · Practice →
- Trapping Rain Water (LeetCode #42) · Practice → (also commonly solved with Two Pointers — this is a multi-pattern problem)
- Car Fleet (LeetCode #853) · Practice →
15. Trie (Prefix Tree)
Pattern Explanation
A Trie is a tree where each node represents a character, and paths from root to leaf spell out words. It’s the go-to structure for prefix-based lookups, autocomplete, and word searches — far more efficient than scanning a list of strings.
When to Recognize It
- The problem involves a dictionary of words and prefix lookups
- You need to search for words with a common prefix
- The problem asks for autocomplete, spell check, or word filtering
Key phrases: “starts with”, “search a word”, “longest word in dictionary”, “replace words”
Python Template
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end = True
def search(self, word):
node = self.root
for char in word:
if char not in node.children:
return False
node = node.children[char]
return node.is_end
def starts_with(self, prefix):
node = self.root
for char in prefix:
if char not in node.children:
return False
node = node.children[char]
return True
Example Problems
- Implement Trie (Prefix Tree) (LeetCode #208) · Practice →
- Word Search II (LeetCode #212) · Practice →
- Design Add and Search Words Data Structure (LeetCode #211) · Practice →
- Replace Words (LeetCode #648) · Practice →
- Longest Word in Dictionary (LeetCode #720) · Practice →
How to Actually Learn These Patterns
Reading this guide is a strong start, but reading is not the same as performing under pressure.
In a real interview, you have 35–45 minutes, an interviewer watching you, and the weight of a job offer on your shoulders. The gap between “I understand the pattern” and “I can execute it fluently while thinking out loud” is enormous. The only way to close that gap is to practice in conditions that feel like the real thing.
That means: time pressure, verbal explanation, clarifying questions, and follow-up challenges.
Practice these patterns in a real mock coding interview, with instant AI feedback on your approach, communication, and code. Start a mock interview on Intervu →
Work through one pattern at a time. For each one, do 3–5 problems, write out your reasoning before you code, and then review what you got wrong. The patterns will start to feel automatic. That’s exactly when you’ll be ready.
Further reading:
- How to Prepare for a Coding Interview in 2026, the complete roadmap from beginner to advanced
- The Grind 75 Practice Pathway, a structured problem list covering all these patterns with AI practice links
- How to Use Intervu with Grind 169, 10-week plan for the expanded 169-problem list
- Why LeetCode Alone Isn’t Enough, and what to practice instead
- Practice Any LeetCode Problem as a full mock interview with AI feedback
Good luck. The patterns are learnable. The interview is winnable.