Skip to main content

LeetCode Patterns Cheat Sheet 2026

All 21 algorithmic patterns — when-to-use signals, time & space complexity, and code templates in Python, Java & C++. One page. Free forever.

By Syed Peera Saheb · · Full pattern guide →
Pattern guide with templates

Pattern Recognition Quick Reference

When you see these signals in a problem statement, reach for the corresponding pattern immediately. Recognizing the pattern is half the work — the template handles the rest.

Problem signal Pattern to use Complexity
Finding max/min subarray of size k Sliding Window O(n)
Pair sum in sorted array Two Pointers O(n)
Searching in sorted array Binary Search O(log n)
Two sum (find complement) Hash Map / Set O(1) average for lookup/insert, O(n) space
Tree height/depth Trees / DFS O(n)
Shortest path in unweighted graph Queue / BFS O(V + E) for graphs, O(n) for trees
Fibonacci and climbing stairs Dynamic Programming Depends on state space
Valid parentheses / bracket matching Stack O(n)
Kth largest/smallest element Heap / Priority Queue O(log n) insert/delete, O(1) peek
Generate all permutations/combinations/subsets Backtracking Exponential
Merge intervals Intervals O(n log n)
Range sum queries Prefix Sum O(n) build, O(1) per query
Number of islands Graphs O(V + E)
Implement Trie (insert/search/startsWith) Trie O(m) per operation where m is word length
Number of connected components Union Find O(α(n)) per operation
Largest rectangle in histogram Monotonic Stack O(n)
Course Schedule (detect cycle) Topological Sort O(V + E)
Detecting cycles (Floyd's algorithm) Linked List O(n)
Jump game Greedy O(n log n)
Single number (XOR trick) Bit Manipulation O(1) or O(log n) for most operations
Rotate image 90° Matrix O(m × n)

All 21 Patterns — Complete Reference

01

Sliding Window

Efficiently process subarrays or substrings of a fixed or variable size.

Time: O(n) Space: O(k) where k is the window size or alphabet size
  • Finding max/min subarray of size k
  • Longest substring without repeating characters
  • Minimum window containing all characters
public int slidingWindow(int[] arr, int k) {
    int left = 0, result = 0;
    Map<Integer, Integer> windowState = new HashMap<>();

    for (int right = 0; right < arr.length; right++) {
        // Expand window: add arr[right]

        // Shrink window when constraint violated
        while (false) { // replace with invalid condition
            // Remove arr[left] from state
            left++;
        }

        // Update result
        result = Math.max(result, right - left + 1);
    }
    return result;
}
Full guide + practice problems →
02

Two Pointers

Use two indices moving toward each other or in the same direction to solve linear problems.

Time: O(n) Space: O(1)
  • Pair sum in sorted array
  • Removing duplicates in-place
  • Container with most water
public int[] twoPointers(int[] arr, int target) {
    int left = 0, right = arr.length - 1;
    while (left < right) {
        int sum = arr[left] + arr[right];
        if (sum == target) return new int[]{left, right};
        else if (sum < target) left++;
        else right--;
    }
    return new int[]{};
}
Full guide + practice problems →
04

Hash Map / Set

Trade space for time using O(1) lookup to find pairs, duplicates, and frequencies.

Time: O(1) average for lookup/insert, O(n) space Space: O(n)
  • Two sum (find complement)
  • Anagram grouping
  • Longest consecutive sequence
// Frequency count
Map<Integer, Integer> freq = new HashMap<>();
for (int x : arr) freq.merge(x, 1, Integer::sum);

// Two sum
public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> seen = new HashMap<>(); // value -> index
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (seen.containsKey(complement))
            return new int[]{seen.get(complement), i};
        seen.put(nums[i], i);
    }
    return new int[]{};
}
Full guide + practice problems →
05

Trees / DFS

Recursive and iterative depth-first traversal for tree structure problems.

Time: O(n) Space: O(h) where h is height; O(n) worst case (skewed)
  • Tree height/depth
  • Path sum problems
  • Lowest common ancestor
class TreeNode {
    int val; TreeNode left, right;
    TreeNode(int val) { this.val = val; }
}

// Generic DFS template
public void dfs(TreeNode node) {
    if (node == null) return; // base case
    // Pre-order: process node here
    dfs(node.left);
    // In-order: process node here
    dfs(node.right);
    // Post-order: process node here
}

// Path sum
public boolean hasPathSum(TreeNode root, int target) {
    if (root == null) return false;
    if (root.left == null && root.right == null) return root.val == target;
    return hasPathSum(root.left, target - root.val) ||
           hasPathSum(root.right, target - root.val);
}
Full guide + practice problems →
06

Queue / BFS

Level-by-level traversal for shortest paths and layer-based problems.

Time: O(V + E) for graphs, O(n) for trees Space: O(V) for the queue
  • Shortest path in unweighted graph
  • Level-order tree traversal
  • Rotting oranges / island flooding
public void bfs(Map<Integer, List<Integer>> graph, int start) {
    Set<Integer> visited = new HashSet<>();
    visited.add(start);
    Queue<Integer> queue = new LinkedList<>();
    queue.offer(start);

    while (!queue.isEmpty()) {
        int node = queue.poll();
        // process node

        for (int neighbor : graph.get(node)) {
            if (!visited.contains(neighbor)) {
                visited.add(neighbor);
                queue.offer(neighbor);
            }
        }
    }
}
Full guide + practice problems →
07

Dynamic Programming

Break problems into overlapping subproblems and build up solutions bottom-up.

Time: Depends on state space Space: O(n) with space optimization
  • Fibonacci and climbing stairs
  • Knapsack variants
  • Longest common subsequence
// 1D DP (Climbing Stairs)
public int climbStairs(int n) {
    int[] dp = new int[n + 1];
    dp[0] = dp[1] = 1;
    for (int i = 2; i <= n; i++) dp[i] = dp[i-1] + dp[i-2];
    return dp[n];
}

// 2D DP (Unique Paths)
public int uniquePaths(int m, int n) {
    int[][] dp = new int[m][n];
    for (int[] row : dp) Arrays.fill(row, 1);
    for (int i = 1; i < m; i++)
        for (int j = 1; j < n; j++)
            dp[i][j] = dp[i-1][j] + dp[i][j-1];
    return dp[m-1][n-1];
}
Full guide + practice problems →
08

Stack

LIFO structure for matching brackets, evaluating expressions, and monotonic problems.

Time: O(n) Space: O(n)
  • Valid parentheses / bracket matching
  • Next greater element
  • Daily temperatures
// Monotonic decreasing stack (next greater element)
public int[] nextGreater(int[] arr) {
    int[] result = new int[arr.length];
    Arrays.fill(result, -1);
    Deque<Integer> stack = new ArrayDeque<>(); // stores indices

    for (int i = 0; i < arr.length; i++) {
        while (!stack.isEmpty() && arr[stack.peek()] < arr[i]) {
            result[stack.pop()] = arr[i];
        }
        stack.push(i);
    }
    return result;
}
Full guide + practice problems →
09

Heap / Priority Queue

Efficiently track the k-th largest/smallest element or merge sorted sequences.

Time: O(log n) insert/delete, O(1) peek Space: O(n)
  • Kth largest/smallest element
  • Merge k sorted lists
  • Task scheduler
// Min-heap
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.offer(val);
int top = minHeap.poll();   // smallest
int peek = minHeap.peek();

// Max-heap
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
maxHeap.offer(val);
int largest = maxHeap.poll();

// Kth largest element
public int kthLargest(int[] nums, int k) {
    PriorityQueue<Integer> pq = new PriorityQueue<>();
    for (int n : nums) {
        pq.offer(n);
        if (pq.size() > k) pq.poll();
    }
    return pq.peek();
}
Full guide + practice problems →
10

Backtracking

Explore all possibilities recursively, pruning invalid branches early.

Time: Exponential Space: O(n) call stack depth
  • Generate all permutations/combinations/subsets
  • N-Queens
  • Sudoku solver
public void backtrack(List<List<Integer>> result, List<Integer> current, int start, int[] nums) {
    result.add(new ArrayList<>(current)); // record current state

    for (int i = start; i < nums.length; i++) {
        // Prune: skip duplicates
        if (i > start && nums[i] == nums[i-1]) continue;

        current.add(nums[i]);                       // choose
        backtrack(result, current, i + 1, nums);    // explore
        current.remove(current.size() - 1);         // un-choose
    }
}
Full guide + practice problems →
11

Intervals

Merge, insert, and count overlapping intervals after sorting by start time.

Time: O(n log n) Space: O(n)
  • Merge intervals
  • Insert interval
  • Meeting rooms (can attend all?)
public int[][] mergeIntervals(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
    List<int[]> merged = new ArrayList<>();
    merged.add(intervals[0]);

    for (int i = 1; i < intervals.length; i++) {
        int[] last = merged.get(merged.size() - 1);
        if (intervals[i][0] <= last[1]) {
            last[1] = Math.max(last[1], intervals[i][1]); // overlap: extend
        } else {
            merged.add(intervals[i]); // no overlap: new interval
        }
    }
    return merged.toArray(new int[0][]);
}
Full guide + practice problems →
12

Prefix Sum

Precompute cumulative sums to answer range queries in O(1).

Time: O(n) build, O(1) per query Space: O(n)
  • Range sum queries
  • Subarray sum equals k
  • Number of subarrays with given sum
public int[] buildPrefix(int[] arr) {
    int[] prefix = new int[arr.length + 1];
    for (int i = 0; i < arr.length; i++) {
        prefix[i + 1] = prefix[i] + arr[i];
    }
    return prefix;
}

public int rangeSum(int[] prefix, int l, int r) {
    return prefix[r + 1] - prefix[l]; // inclusive [l, r]
}
Full guide + practice problems →
13

Graphs

DFS and BFS on adjacency lists for connectivity, cycles, and path problems.

Time: O(V + E) Space: O(V) for visited set
  • Number of islands
  • Clone graph
  • Course schedule (cycle detection)
public int numIslands(char[][] grid) {
    int count = 0;
    for (int r = 0; r < grid.length; r++) {
        for (int c = 0; c < grid[0].length; c++) {
            if (grid[r][c] == '1') {
                dfs(grid, r, c);
                count++;
            }
        }
    }
    return count;
}

private void dfs(char[][] grid, int r, int c) {
    if (r < 0 || r >= grid.length || c < 0 || c >= grid[0].length || grid[r][c] != '1') return;
    grid[r][c] = '0'; // mark visited
    dfs(grid, r+1, c); dfs(grid, r-1, c);
    dfs(grid, r, c+1); dfs(grid, r, c-1);
}
Full guide + practice problems →
14

Trie

Prefix tree for efficient string search, autocomplete, and word matching.

Time: O(m) per operation where m is word length Space: O(ALPHABET_SIZE × m × n)
  • Implement Trie (insert/search/startsWith)
  • Word search II
  • Design add/search words
class TrieNode {
    Map<Character, TrieNode> children = new HashMap<>();
    boolean isEnd = false;
}

class Trie {
    private final TrieNode root = new TrieNode();

    public void insert(String word) {
        TrieNode node = root;
        for (char ch : word.toCharArray()) {
            node.children.putIfAbsent(ch, new TrieNode());
            node = node.children.get(ch);
        }
        node.isEnd = true;
    }

    public boolean search(String word) {
        TrieNode node = root;
        for (char ch : word.toCharArray()) {
            if (!node.children.containsKey(ch)) return false;
            node = node.children.get(ch);
        }
        return node.isEnd;
    }
}
Full guide + practice problems →
15

Union Find

Disjoint set union for grouping, connectivity, and cycle detection.

Time: O(α(n)) per operation Space: O(n)
  • Number of connected components
  • Redundant connection (cycle detection)
  • Accounts merge
class UnionFind {
    int[] parent, rank;

    UnionFind(int n) {
        parent = new int[n];
        rank = new int[n];
        for (int i = 0; i < n; i++) parent[i] = i;
    }

    public int find(int x) {
        if (parent[x] != x) parent[x] = find(parent[x]); // path compression
        return parent[x];
    }

    public boolean union(int x, int y) {
        int px = find(x), py = find(y);
        if (px == py) return false;
        if (rank[px] < rank[py]) parent[px] = py;
        else if (rank[px] > rank[py]) parent[py] = px;
        else { parent[py] = px; rank[px]++; }
        return true;
    }
}
Full guide + practice problems →
16

Monotonic Stack

Maintain a sorted stack to find next/previous greater or smaller elements in O(n).

Time: O(n) Space: O(n)
  • Largest rectangle in histogram
  • Trapping rain water
  • Daily temperatures
// Largest Rectangle in Histogram
public int largestRectangle(int[] heights) {
    Deque<Integer> stack = new ArrayDeque<>();
    stack.push(-1);
    int maxArea = 0;

    for (int i = 0; i <= heights.length; i++) {
        int h = (i == heights.length) ? 0 : heights[i];
        while (stack.peek() != -1 && heights[stack.peek()] >= h) {
            int height = heights[stack.pop()];
            int width = i - stack.peek() - 1;
            maxArea = Math.max(maxArea, height * width);
        }
        stack.push(i);
    }
    return maxArea;
}
Full guide + practice problems →
17

Topological Sort

Linear ordering of vertices in a DAG — essential for dependency problems.

Time: O(V + E) Space: O(V)
  • Course Schedule (detect cycle)
  • Course Schedule II (ordering)
  • Alien dictionary
// Kahn's Algorithm (BFS-based)
public int[] topoSort(int n, int[][] prerequisites) {
    int[] inDegree = new int[n];
    List<List<Integer>> adj = new ArrayList<>();
    for (int i = 0; i < n; i++) adj.add(new ArrayList<>());

    for (int[] edge : prerequisites) {
        adj.get(edge[1]).add(edge[0]);
        inDegree[edge[0]]++;
    }

    Queue<Integer> queue = new LinkedList<>();
    for (int i = 0; i < n; i++) if (inDegree[i] == 0) queue.offer(i);

    int[] order = new int[n];
    int idx = 0;
    while (!queue.isEmpty()) {
        int node = queue.poll();
        order[idx++] = node;
        for (int nei : adj.get(node)) {
            if (--inDegree[nei] == 0) queue.offer(nei);
        }
    }
    return idx == n ? order : new int[]{}; // empty = cycle exists
}
Full guide + practice problems →
18

Linked List

Pointer manipulation for in-place list operations without extra memory.

Time: O(n) Space: O(1) for in-place operations
  • Detecting cycles (Floyd's algorithm)
  • Reversing a linked list
  • Finding middle of list
class ListNode {
    int val; ListNode next;
    ListNode(int val) { this.val = val; }
}

// Reverse linked list in-place
public ListNode reverse(ListNode head) {
    ListNode prev = null, curr = head;
    while (curr != null) {
        ListNode next = curr.next;
        curr.next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

// Fast / slow pointer
public boolean hasCycle(ListNode head) {
    ListNode slow = head, fast = head;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
        if (slow == fast) return true;
    }
    return false;
}
Full guide + practice problems →
19

Greedy

Make the locally optimal choice at each step to achieve a globally optimal solution.

Time: O(n log n) Space: O(1)
  • Jump game
  • Gas station
  • Meeting rooms
// Jump Game II — greedy
public int jump(int[] nums) {
    int jumps = 0, currentEnd = 0, farthest = 0;
    for (int i = 0; i < nums.length - 1; i++) {
        farthest = Math.max(farthest, i + nums[i]);
        if (i == currentEnd) {
            jumps++;
            currentEnd = farthest;
        }
    }
    return jumps;
}
Full guide + practice problems →
20

Bit Manipulation

Use bitwise operations to solve XOR, subset, and number theory problems.

Time: O(1) or O(log n) for most operations Space: O(1)
  • Single number (XOR trick)
  • Number of 1 bits (Hamming weight)
  • Counting bits
// Common bit tricks
int getBit(int n, int i) { return (n >> i) & 1; }
int setBit(int n, int i) { return n | (1 << i); }
int clearBit(int n, int i) { return n & ~(1 << i); }
boolean isPowerOf2(int n) { return n > 0 && (n & (n - 1)) == 0; }
int lowestSetBit(int n) { return n & (-n); }
int clearLowestBit(int n) { return n & (n - 1); }

// XOR: find single number where all others appear twice
public int singleNumber(int[] nums) {
    int result = 0;
    for (int n : nums) result ^= n;
    return result;
}
Full guide + practice problems →
21

Matrix

Navigate 2D grids with DFS/BFS, rotation, spiral traversal, and flood fill.

Time: O(m × n) Space: O(m × n) for BFS/DFS, O(1) for in-place tricks
  • Rotate image 90°
  • Spiral matrix traversal
  • Set matrix zeros
int[][] DIRS = {{1,0},{-1,0},{0,1},{0,-1}};

public void bfsGrid(int[][] grid, int startR, int startC) {
    int rows = grid.length, cols = grid[0].length;
    Queue<int[]> queue = new LinkedList<>();
    Set<String> visited = new HashSet<>();
    queue.offer(new int[]{startR, startC});
    visited.add(startR + "," + startC);

    while (!queue.isEmpty()) {
        int[] curr = queue.poll();
        int r = curr[0], c = curr[1];
        for (int[] d : DIRS) {
            int nr = r + d[0], nc = c + d[1];
            String key = nr + "," + nc;
            if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && !visited.contains(key)) {
                visited.add(key);
                queue.offer(new int[]{nr, nc});
            }
        }
    }
}
Full guide + practice problems →

Ready to practice?

Use the full Coding Interview Patterns guide to study each pattern in depth, then solve curated problems from our problem set. Filter by company to target the exact patterns asked at Google, Meta, Amazon, and Microsoft.

Buy me a coffee
Daily Practice
0/0