← All articles
13 min read

Coding Interview Patterns Cheat Sheet (2026 Templates)

Most coding interview problems are variations of about fifteen patterns. This cheat sheet gives you the recognition signals, a Python template, complexity, and practice problems for each.

Coding interview patterns are reusable problem-solving templates, such as sliding window, two pointers, BFS, and monotonic stack, that solve whole families of LeetCode problems. Roughly fifteen patterns cover most questions asked at FAANG and similar companies in 2026. The fastest way to improve is to learn each pattern's recognition signals and a reliable template, then practice two or three classic problems per pattern until you can spot the pattern from the problem statement alone.

This cheat sheet gives you all of that in one place, in Python.

Key Takeaways

  • Pattern recognition beats problem count. Fifteen well-understood patterns are worth more than 400 memorized solutions.
  • Constraints are clues: n up to 10^5 usually needs O(n log n) or better, while n up to 20 allows exponential backtracking or bitmask approaches.
  • Most of these templates run in linear or n log n time because each element is processed a bounded number of times.
  • Learn the template, then the variations. Interviewers in 2026 often twist well-known problems to test understanding.
  • Dynamic programming is a pattern family of its own; our dynamic programming patterns guide covers it in depth.

Signal to Pattern Lookup Table

Use this table when you read a new problem. Match the phrasing or constraint to a starting pattern.

Signal in the problemLikely pattern
Longest or shortest contiguous subarray or substring with a conditionSliding window
Sorted array, find a pair or triplet with a targetTwo pointers
Linked list cycle, middle node, or duplicate in range 1..nFast and slow pointers
Sorted input, or "find the minimum value such that..."Binary search, or binary search on answer
Minimize the maximum, maximize the minimumBinary search on answer
Shortest path in an unweighted grid or graph, level by levelBFS
Explore all connected cells, count islands, path existenceDFS (or BFS)
Prerequisites, dependencies, build orderTopological sort
Dynamic connectivity, grouping, "are these connected"Union-find
k largest, k smallest, k most frequent, merge k sortedHeap
Next greater or smaller element, span, histogram areaMonotonic stack
Overlapping meetings, merging ranges, minimum roomsIntervals
All subsets, permutations, combinations, board searchBacktracking
Prefix matching, autocomplete, word search with many wordsTrie
Range sums, subarray sum equals kPrefix sums plus hash map
Count ways, min or max cost, choices that overlapDynamic programming

Sliding Window

Sliding window is a technique that maintains a contiguous range of an array or string and expands or shrinks it to satisfy a condition, avoiding recomputation from scratch.

Recognition signals: contiguous subarray or substring, longest or shortest, at most k distinct, contains all characters of.

from collections import defaultdict

def longest_window(s, k):
    counts = defaultdict(int)
    left = 0
    best = 0
    for right, ch in enumerate(s):
        counts[ch] += 1
        while len(counts) > k:
            counts[s[left]] -= 1
            if counts[s[left]] == 0:
                del counts[s[left]]
            left += 1
        best = max(best, right - left + 1)
    return best

Complexity: O(n) time, since each index enters and leaves the window once. O(k) or O(alphabet) space.

Classic problems: Longest Substring Without Repeating Characters (3), Minimum Window Substring (76), Longest Repeating Character Replacement (424).

Two Pointers

Two pointers is a technique that uses two indices, often starting at opposite ends of a sorted array, and moves them inward based on a comparison.

Recognition signals: sorted input, pair or triplet summing to a target, palindrome checks, in-place partitioning.

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

Complexity: O(n) time after sorting (O(n log n) if you must sort first), O(1) extra space.

Classic problems: Two Sum II (167), 3Sum (15), Container With Most Water (11).

Fast and Slow Pointers

Fast and slow pointers (Floyd's tortoise and hare) move two pointers at different speeds through a sequence. If there is a cycle, the fast pointer eventually meets the slow one.

Recognition signals: linked list cycle, middle of a linked list, a value sequence that may loop (Happy Number), duplicate number in an array of values 1..n.

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

Complexity: O(n) time, O(1) space.

Classic problems: Linked List Cycle (141), Middle of the Linked List (876), Find the Duplicate Number (287).

Binary Search and Binary Search on the Answer

Binary search halves a search space each step. Binary search on the answer applies the same idea to the range of possible answers, using a monotonic feasibility check.

Recognition signals: sorted or rotated input, "find the first or last position," "minimum capacity or speed such that," "minimize the maximum," and very large value ranges with an O(n) check.

def min_feasible(lo, hi, feasible):
    while lo < hi:
        mid = (lo + hi) // 2
        if feasible(mid):
            hi = mid
        else:
            lo = mid + 1
    return lo

def min_eating_speed(piles, h):
    def feasible(speed):
        hours = sum((p + speed - 1) // speed for p in piles)
        return hours <= h
    return min_feasible(1, max(piles), feasible)

This "first true" template avoids most off-by-one bugs: feasible must be false for small values and true from some point onward, and the loop returns the first true value.

Complexity: O(log n) for array search. O(n log R) for answer search, where R is the answer range.

Classic problems: Search in Rotated Sorted Array (33), Koko Eating Bananas (875), Capacity to Ship Packages Within D Days (1011).

BFS and DFS

Breadth-first search (BFS) explores a graph level by level using a queue and finds shortest paths in unweighted graphs. Depth-first search (DFS) explores as far as possible along each branch using recursion or a stack.

Recognition signals: grids, islands, connected components, shortest number of steps (BFS), path existence or exhaustive exploration (DFS), tree traversals.

from collections import deque

def shortest_path_grid(grid, start, target):
    rows, cols = len(grid), len(grid[0])
    queue = deque([(start[0], start[1], 0)])
    seen = {start}
    while queue:
        r, c, dist = queue.popleft()
        if (r, c) == target:
            return dist
        for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
            nr, nc = r + dr, c + dc
            if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 0 and (nr, nc) not in seen:
                seen.add((nr, nc))
                queue.append((nr, nc, dist + 1))
    return -1

def count_islands(grid):
    rows, cols = len(grid), len(grid[0])
    def dfs(r, c):
        if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] != "1":
            return
        grid[r][c] = "0"
        dfs(r + 1, c)
        dfs(r - 1, c)
        dfs(r, c + 1)
        dfs(r, c - 1)
    count = 0
    for r in range(rows):
        for c in range(cols):
            if grid[r][c] == "1":
                dfs(r, c)
                count += 1
    return count

Mark nodes as visited when you enqueue them, not when you dequeue them, or BFS can add the same cell many times. For very large grids, note that Python's default recursion limit is around 1,000, so an iterative DFS may be safer.

Complexity: O(V + E) time, or O(rows × cols) for grids. O(V) space.

Classic problems: Number of Islands (200), Rotting Oranges (994), Binary Tree Level Order Traversal (102).

Topological Sort

Topological sort orders the nodes of a directed acyclic graph so that every edge points from earlier to later. Kahn's algorithm repeatedly removes nodes with zero incoming edges.

Recognition signals: prerequisites, dependencies, build order, "is it possible to finish," detecting a cycle in a directed graph.

from collections import deque

def topo_order(n, edges):
    graph = [[] for _ in range(n)]
    indegree = [0] * n
    for before, after in edges:
        graph[before].append(after)
        indegree[after] += 1
    queue = deque(i for i in range(n) if indegree[i] == 0)
    order = []
    while queue:
        node = queue.popleft()
        order.append(node)
        for nxt in graph[node]:
            indegree[nxt] -= 1
            if indegree[nxt] == 0:
                queue.append(nxt)
    return order if len(order) == n else []

An empty result means the graph has a cycle. Note the edge direction: LeetCode's Course Schedule gives [course, prerequisite], so you add an edge from prerequisite to course.

Complexity: O(V + E) time and space.

Classic problems: Course Schedule (207), Course Schedule II (210), Alien Dictionary (269).

Union-Find

Union-find (disjoint set union) is a data structure that tracks which elements belong to the same group and merges groups efficiently. With path compression and union by rank, operations run in nearly constant amortized time.

Recognition signals: connected components when edges arrive over time, redundant connection, grouping equivalent items (accounts, synonyms), Kruskal's minimum spanning tree.

class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n
        self.components = n

    def find(self, x):
        while self.parent[x] != x:
            self.parent[x] = self.parent[self.parent[x]]
            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
        self.components -= 1
        return True

Complexity: O(α(n)) amortized per operation, where α is the inverse Ackermann function and effectively constant. O(n) space.

Classic problems: Number of Connected Components in an Undirected Graph (323), Redundant Connection (684), Accounts Merge (721).

Heap and Top-K

A heap is a binary tree-based priority queue that returns the smallest (min-heap) or largest (max-heap) element in O(log n). For top-k problems, keep a heap of size k.

Recognition signals: k largest, k smallest, k most frequent, k closest, merge k sorted lists, running median, scheduling by priority.

import heapq
from collections import Counter

def top_k_frequent(nums, k):
    heap = []
    for value, freq in Counter(nums).items():
        heapq.heappush(heap, (freq, value))
        if len(heap) > k:
            heapq.heappop(heap)
    return [value for freq, value in heap]

Python's heapq is a min-heap only. To simulate a max-heap, push negated values. Keeping a min-heap of size k to find the k largest is the key trick.

Complexity: O(n log k) time, O(k) heap space (plus the frequency map).

Classic problems: Kth Largest Element in an Array (215), Top K Frequent Elements (347), Merge K Sorted Lists (23).

Knowing which pattern applies is half the battle, and recall under pressure is the other half. TechScreen is an invisible AI interview assistant that helps you identify the pattern and structure the solution in real time during HackerRank, CoderPad, and Zoom rounds. New users get 3 free tokens to try it.

Get started free →

Monotonic Stack

A monotonic stack is a stack whose elements stay in increasing or decreasing order. When a new element breaks the order, popped elements have found their answer.

Recognition signals: next greater or next smaller element, days until a warmer temperature, stock span, largest rectangle in a histogram, trapping rain water.

def next_greater(nums):
    result = [-1] * len(nums)
    stack = []
    for i, value in enumerate(nums):
        while stack and nums[stack[-1]] < value:
            result[stack.pop()] = value
        stack.append(i)
    return result

Store indices rather than values, so you can compute distances (as in Daily Temperatures) and write results back in place.

Complexity: O(n) time, since each index is pushed and popped at most once. O(n) space.

Classic problems: Daily Temperatures (739), Next Greater Element I (496), Largest Rectangle in Histogram (84).

Intervals

Interval problems involve ranges with a start and end. The standard approach is to sort by start time and then sweep, merging or counting overlaps.

Recognition signals: meetings, bookings, overlapping ranges, insert a range, minimum number of rooms or arrows.

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

For "minimum meeting rooms," sort by start and keep a min-heap of end times; the heap's maximum size is the answer.

Complexity: O(n log n) time for the sort, O(n) space for output.

Classic problems: Merge Intervals (56), Insert Interval (57), Non-overlapping Intervals (435).

Backtracking

Backtracking builds candidate solutions incrementally and abandons a path as soon as it cannot lead to a valid answer.

Recognition signals: generate all subsets, permutations, or combinations; place items under constraints (N-Queens, Sudoku); search for a word on a board; small n (often 20 or less).

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

Three choices define every backtracking variant: what the state is, which choices are available at each step, and when to record or prune. To skip duplicates, sort first and skip nums[i] == nums[i - 1] when i > start.

Complexity: exponential. Subsets are O(n × 2^n), permutations O(n × n!).

Classic problems: Subsets (78), Combination Sum (39), Word Search (79).

Trie

A trie (prefix tree) stores strings character by character so that all words sharing a prefix share a path. Lookups and prefix checks run in time proportional to word length.

Recognition signals: prefix search, autocomplete, word dictionary with wildcards, searching many words in a grid at once.

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_word = False

class Trie:
    def __init__(self):
        self.root = TrieNode()

    def insert(self, word):
        node = self.root
        for ch in word:
            node = node.children.setdefault(ch, TrieNode())
        node.is_word = True

    def _walk(self, text):
        node = self.root
        for ch in text:
            if ch not in node.children:
                return None
            node = node.children[ch]
        return node

    def search(self, word):
        node = self._walk(word)
        return node is not None and node.is_word

    def starts_with(self, prefix):
        return self._walk(prefix) is not None

Complexity: O(L) per insert or lookup, where L is the word length. Space is O(total characters stored).

Classic problems: Implement Trie (208), Design Add and Search Words Data Structure (211), Word Search II (212).

Prefix Sums

A prefix sum array stores the running total up to each index, so any range sum becomes a subtraction. Combined with a hash map, prefix sums count subarrays with a target sum in one pass.

Recognition signals: range sum queries, "number of subarrays that sum to k," subarray divisible by k, equal numbers of 0s and 1s, 2D region sums.

from collections import defaultdict

def subarray_sum_equals_k(nums, k):
    counts = defaultdict(int)
    counts[0] = 1
    running = 0
    total = 0
    for value in nums:
        running += value
        total += counts[running - k]
        counts[running] += 1
    return total

Unlike sliding window, this works with negative numbers, which is the main reason to choose prefix sums over a window.

Complexity: O(n) time and O(n) space.

Classic problems: Subarray Sum Equals K (560), Range Sum Query - Immutable (303), Contiguous Array (525).

Dynamic Programming

Dynamic programming solves problems with overlapping subproblems and optimal substructure by storing results of subproblems. Signals include "number of ways," "minimum or maximum cost," and decisions at each step that affect future options. DP has enough sub-patterns (linear, grid, subsequence, knapsack, interval, tree, bitmask) that it deserves its own reference; use our dynamic programming patterns for FAANG guide for templates and problem lists.

Classic problems: Climbing Stairs (70), Coin Change (322), Longest Common Subsequence (1143).

Complexity Summary

PatternTypical timeTypical extra space
Sliding windowO(n)O(k)
Two pointersO(n) after sortO(1)
Fast and slow pointersO(n)O(1)
Binary search on answerO(n log R)O(1)
BFS / DFSO(V + E)O(V)
Topological sortO(V + E)O(V + E)
Union-findO(α(n)) per opO(n)
Heap top-kO(n log k)O(k)
Monotonic stackO(n)O(n)
IntervalsO(n log n)O(n)
BacktrackingExponentialO(n) recursion depth
TrieO(L) per opO(total chars)
Prefix sumsO(n)O(n)

How Should You Practice These Patterns?

  1. One pattern at a time. Spend two to three days per pattern, solving four to eight problems, starting easy.
  2. Write the template from memory first. Before each session, write the pattern's template on a blank file. This is the part worth memorizing. The rest should be understood, as we explain in should you memorize LeetCode solutions.
  3. Then mix. After covering all patterns, switch to randomized problems so you practice recognition, not just execution. A curated list helps here; see our comparison of Blind 75, NeetCode 150, and Grind 75.
  4. State complexity out loud. Interviewers at Google and Meta almost always ask for it, and naming it unprompted is a strong signal.
  5. Track misses by pattern. If you keep missing monotonic stack problems, that is where your next three sessions go.

For how much total volume to aim for, see how many LeetCode problems you need before a FAANG interview. If you are still deciding between Python and another language, our guide on which language to use in a coding interview covers the trade-offs.

Even with every template memorized, a live round can throw a pattern you cannot place. TechScreen runs invisibly during your screen share and gives real-time hints, templates, and complexity analysis when you need them. Claim 3 free tokens and test it on a mock interview first.

Get started free →

Frequently Asked Questions

What are the most common coding interview patterns?

The patterns that appear most often in 2026 coding interviews are sliding window, two pointers, fast and slow pointers, binary search (including binary search on the answer), BFS and DFS, topological sort, union-find, heaps for top-k problems, monotonic stacks, interval merging, backtracking, tries, prefix sums, and dynamic programming. Together these cover the large majority of medium-difficulty problems asked at Google, Meta, Amazon, and similar companies.

How do I recognize which pattern a LeetCode problem uses?

Look for signals in the problem statement and constraints. Contiguous subarray or substring suggests sliding window or prefix sums. Sorted input suggests two pointers or binary search. Minimize the maximum suggests binary search on the answer. Shortest path in an unweighted graph suggests BFS. Dependencies or ordering suggest topological sort. Next greater element suggests a monotonic stack. All combinations or permutations suggest backtracking. Constraints also help: n up to 20 often means exponential search is acceptable.

What is the difference between two pointers and sliding window?

Both use two indices, but they solve different problems. Sliding window keeps a contiguous range between a left and right pointer that move in the same direction, and maintains some state about the window such as a sum or character counts. Two pointers more often start at opposite ends of a sorted array and move toward each other based on a comparison. Sliding window is effectively a specialized same-direction form of two pointers.

What is binary search on the answer?

Binary search on the answer is a technique where you binary search over the range of possible answers instead of over an input array. It applies when you can write a feasibility check that is monotonic: if a value works, every larger (or smaller) value also works. Classic examples are Koko Eating Bananas, Capacity to Ship Packages Within D Days, and Split Array Largest Sum. Complexity is O(n log R), where R is the size of the answer range.

How many patterns do I need to learn for FAANG interviews?

Learning around fifteen core patterns is enough for most FAANG coding rounds. The important part is depth: you should be able to recognize each pattern from the problem statement, write its template from memory without bugs, and adapt it to variants. Solving four to eight problems per pattern usually builds that recognition, which works out to roughly 80 to 150 problems in total.

Which language is best for coding interview pattern templates?

Python is the most popular choice because its syntax is concise and its standard library includes deque, heapq, bisect, Counter, and defaultdict, which cover most pattern needs. The trade-off is that Python's heapq only implements a min-heap, so you negate values for a max-heap. Java and C++ are equally acceptable; choose the language you are fastest and most accurate in.

Is a monotonic stack the same as a regular stack?

A monotonic stack is a regular stack with an invariant: its elements are kept in strictly increasing or decreasing order. Before pushing a new element, you pop every element that would break the order, and each pop is the moment you resolve that element's answer, such as its next greater element. Because every element is pushed and popped at most once, the total runtime is O(n).

Ready to use AI assistance in your next interview?

TechScreen is the invisible AI assistant trusted by engineers interviewing at Google, Meta, Amazon, and hundreds of other companies. Start with 3 free tokens — no credit card required.

Ace your next interview →