LeetCopilot Logo
LeetCopilot

How to Know Which Algorithm to Use on LeetCode (Pattern Decision Tree + Cheat Sheet)

David Ng
Jan 14, 2026
22 min read
LeetCodeAlgorithmsInterview PrepProblem SolvingStudy StrategyCoding Patterns
Stop guessing. Use this 2-minute decision checklist and a cheat sheet of the 12 core algorithm patterns (with signals, templates, and common traps).

I used to read a LeetCode problem and freeze. "Is this DP? Greedy? Graph? Maybe Two Pointers?"

After staring for 20 minutes, I'd try something random. Usually wrong. Then I'd look at the solution and think: "How was I supposed to know that?"

That frustration isn't a talent gap. It's a missing selection framework.

After failing enough interviews and finally building a systematic approach, here's what I learned: pattern selection is a skill, not intuition. You can learn it with a checklist, and once you have it, LeetCode becomes dramatically easier.

This guide gives you the exact decision process I use now—the one that took me from random guessing to solving Mediums in 25 minutes.

One-Minute Decision: What's Actually Blocking You

If you stare at the screen and can't start:
You're missing pattern recognition. Use the 2-minute checklist below and force yourself to name a pattern before coding.

If you get brute force but can't optimize:
You're missing the "bottleneck → fix" rule. Identify what makes brute force slow (nested loop? repeated work?), then apply the pattern that fixes it (hash map, sorting, prefix sums).

If you keep choosing the wrong pattern:
You're skipping constraints. Read constraints FIRST. Do the 10-second complexity check. Then select a pattern.

If you know the pattern but fail interviews:
Your communication order is wrong. Say: constraints → candidate approaches → pick one → complexity → code. Not: silence → code → "I think it works?"

Don't:

  • Start coding before naming a pattern (random wandering)
  • Spend 15+ minutes thinking without trying brute force (paralysis)
  • Skip the constraints (they tell you the answer)

The Core Insight: There Are Only ~12 Patterns

Here's the realization that changed my prep:

Most LeetCode problems are NOT testing your ability to invent new algorithms. They're testing whether you can:

  1. Recognize the pattern
  2. Apply a known template
  3. Communicate trade-offs

Once I understood that, I stopped treating each problem as a new puzzle. Instead, I asked: "Which of my 12 templates does this match?"

That mental shift cut my problem-solving time in half.

Quick Verdict Table: Which Pattern to Use

Use this table to jump from problem signals to the right pattern:

If You See This...Use This PatternWhy It Works
"contiguous subarray/substring"Sliding WindowCan expand/contract while maintaining state
"sorted array" / "pair sum"Two PointersConverging pointers exploit sorted order
"kth largest/smallest", "top K"HeapO(n log k) for extraction
"minimum steps", "shortest path" (unweighted)BFSGuarantees shortest in unweighted graphs
"all combinations/permutations"BacktrackingEnumerate with pruning
"overlapping subproblems", "optimal"DPCache repeated computation
"schedule", "intervals", "maximize"Greedy + SortLocally optimal → globally optimal
"next greater element"Monotonic StackMaintains order for nearest queries
"sum in range", "subarray sum = k"Prefix SumO(1) range queries after O(n) precompute
"frequency", "duplicates", "anagrams"Hash MapO(1) lookup and counting
"cycle detection", "connected components"DFS/BFS + VisitedGraph traversal
"minimum X such that...", monotonic propertyBinary SearchLog-time search on answer space

The 2-Minute Algorithm Selection Checklist

Before you write a single line of code, answer these questions in order:

Step 1: What's the input shape?

Input TypeLikely Patterns
Array / StringHash Map, Two Pointers, Sliding Window, Prefix Sum
Matrix / GridBFS, DFS, DP
TreeDFS, BFS, Recursion
GraphBFS, DFS, Union Find, Topological Sort
IntervalsGreedy + Sort, Heap
Stream / OnlineHeap, Monotonic structures

Step 2: What are you returning?

Output TypeLikely Patterns
Boolean ("is it possible?")BFS, DFS, DP
Number (min/max/count)DP, Greedy, Sliding Window, Prefix Sum
Index / SubarrayTwo Pointers, Sliding Window, Binary Search
All solutions (list)Backtracking
Single path or orderBFS, DFS, Topological Sort

Step 3: What do constraints allow?

This is the step most people skip. Constraints tell you the answer.

ConstraintWhat It Means
n ≤ 10^5O(n²) will TLE. Need O(n) or O(n log n)
n ≤ 2000O(n²) might pass. O(n³) will TLE
n ≤ 20Backtracking/bitmask OK (2^20 ≈ 10^6)
n ≤ 10Brute force everything OK

The rule: If constraints are tight, you need an optimized pattern. If constraints are loose, brute force may work.

Step 4: What keywords appear?

Certain words are dead giveaways:

  • "longest/shortest subarray" → Sliding Window
  • "sorted" → Two Pointers or Binary Search
  • "all" or "every" → Backtracking
  • "minimum steps" → BFS
  • "schedule" or "intervals" → Greedy

Step 5: Force a name

Before coding, say:

"This is a Sliding Window problem because we need the longest contiguous segment satisfying a condition."

That single sentence prevents random wandering and is exactly what interviewers want to hear.

The 12 Core Patterns (With Templates)

Pattern 1: Hash Map (Counting + Lookup)

Use when: Fast membership, frequency counting, pair sums, deduplication.

Classic problems: Two Sum, Group Anagrams, Top K Frequent Elements

The signal words: "frequency," "duplicate," "pair with sum," "anagram"

Template:

python
seen = {}
for i, x in enumerate(arr):
    complement = target - x
    if complement in seen:
        return [seen[complement], i]
    seen[x] = i

Common mistake I made: Using a set when I needed counts. Sets track existence; dicts track counts/indices.

Pattern 2: Two Pointers

Use when: Sorted data, or you can sort it. Pairs, triplets, partitioning.

Classic problems: 3Sum, Container With Most Water, Remove Duplicates

The signal words: "sorted," "pair," "triplet," "palindrome," "partition"

Template:

python
l, r = 0, len(arr) - 1
while l < r:
    if condition:
        l += 1
    else:
        r -= 1

Common mistake I made: Sorting the array when the problem asked for original indices. Sorting changes indices—check if that matters.

Pattern 3: Sliding Window

Use when: Best contiguous segment (longest, shortest, with some property).

Classic problems: Longest Substring Without Repeating Characters, Minimum Window Substring

The signal words: "contiguous," "longest/shortest substring/subarray," "at most K"

Template:

python
l = 0
for r in range(len(arr)):
    # add arr[r] to window
    while window_invalid():
        # remove arr[l] from window
        l += 1
    update_answer()

Common mistake I made: Using sliding window when negatives were present. Negatives break the monotonic property—use prefix sums instead.

Pattern 4: Prefix Sum

Use when: Range sums, "subarray sum equals K," or negatives are involved.

Classic problems: Subarray Sum Equals K, Range Sum Query

The signal words: "sum of subarray," "count subarrays with sum," "range query"

Template:

python
prefix = 0
count = {0: 1}  # Critical: don't forget this
for x in arr:
    prefix += x
    ans += count.get(prefix - k, 0)
    count[prefix] = count.get(prefix, 0) + 1

Common mistake I made: Forgetting count[0] = 1. This handles subarrays starting from index 0.

When to use prefix sum vs sliding window:

  • Sliding window: Non-negative values, "at most" style conditions
  • Prefix sum: Any values (including negatives), exact sum conditions

Use when: Answer has a monotonic property. "Minimum X such that..." or searching in sorted data.

Classic problems: Koko Eating Bananas, Search in Rotated Sorted Array, Capacity To Ship Packages

The signal words: "minimum X such that," "maximize minimum," "sorted," "threshold"

Template (search on answer):

python
def feasible(x):
    # Can we achieve the goal with x?
    return True/False

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

Common mistake I made: Wrong bounds. Make sure lo points to an infeasible value and hi points to a feasible value (or vice versa, consistently).

Pattern 6: Monotonic Stack

Use when: "Next greater/smaller element" or maintaining a monotonic property.

Classic problems: Daily Temperatures, Next Greater Element, Largest Rectangle in Histogram

The signal words: "next greater," "next smaller," "temperatures," "histogram"

Template:

python
stack = []
for i, x in enumerate(arr):
    while stack and arr[stack[-1]] < x:
        j = stack.pop()
        result[j] = x  # or i - j for distance
    stack.append(i)

Common mistake I made: Storing values instead of indices. You almost always need indices for position-based answers.

Pattern 7: Heap / Priority Queue

Use when: Repeatedly extract the "best" item (min or max).

Classic problems: Top K Frequent Elements, Merge K Sorted Lists, Task Scheduler

The signal words: "top K," "kth smallest/largest," "merge K," "schedule"

Template:

python
import heapq
heap = []
for item in items:
    heapq.heappush(heap, (priority, item))
    if len(heap) > k:
        heapq.heappop(heap)

Common mistake I made: Not controlling heap size. For "top K," keep heap size at K to get O(n log k) instead of O(n log n).

Pattern 8: BFS

Use when: Shortest path in unweighted graphs, level-order traversal, "minimum steps."

Classic problems: Word Ladder, Rotting Oranges, Binary Tree Level Order Traversal

The signal words: "minimum steps," "shortest path," "nearest," "level order"

Template:

python
from collections import deque
q = deque([start])
visited = {start}
steps = 0
while q:
    for _ in range(len(q)):
        node = q.popleft()
        if node == target:
            return steps
        for neighbor in get_neighbors(node):
            if neighbor not in visited:
                visited.add(neighbor)
                q.append(neighbor)
    steps += 1

Common mistake I made: Marking visited when dequeuing instead of enqueuing. Mark when you add to queue, not when you process—otherwise you add duplicates.

Pattern 9: DFS

Use when: Exploring all paths, counting components, checking connectivity, cycle detection.

Classic problems: Number of Islands, Clone Graph, Course Schedule (cycle detection)

The signal words: "connected," "components," "islands," "path exists," "cycle"

Template:

python
def dfs(node):
    visited.add(node)
    for neighbor in get_neighbors(node):
        if neighbor not in visited:
            dfs(neighbor)

Common mistake I made: Missing the three-state coloring for cycle detection (unvisited/visiting/visited). Two states work for undirected graphs; directed graphs need three.

Pattern 10: Backtracking

Use when: Generate all solutions under constraints.

Classic problems: Subsets, Permutations, N-Queens, Combination Sum

The signal words: "all subsets," "all permutations," "all combinations," "generate all"

Template:

python
def backtrack(path, start):
    if is_solution(path):
        result.append(path[:])
        return
    for i in range(start, len(choices)):
        path.append(choices[i])
        backtrack(path, i + 1)  # or i for reuse
        path.pop()

Common mistake I made: Forgetting path[:] when adding to results. Lists are mutable—you need a copy.

Pattern 11: Dynamic Programming

Use when: Overlapping subproblems + optimal value or count of ways.

Classic problems: Climbing Stairs, House Robber, Longest Common Subsequence

The signal words: "minimum cost," "maximum profit," "count ways," "optimal"

First move: Define state → transition → base case.

Template (1D):

python
dp = [0] * (n + 1)
dp[0] = base_case
for i in range(1, n + 1):
    dp[i] = transition(dp[i-1], dp[i-2], ...)
return dp[n]

Common mistake I made: Wrong state definition. If your DP array blows up in memory, you probably included too much information in the state.

Pattern 12: Greedy + Sorting

Use when: Local optimal choices lead to global optimal, especially with intervals.

Classic problems: Meeting Rooms II, Merge Intervals, Non-overlapping Intervals

The signal words: "schedule," "intervals," "select maximum," "minimize removals"

Template (interval scheduling):

python
intervals.sort(key=lambda x: x[1])  # Sort by end time
count = 0
end = float('-inf')
for start, finish in intervals:
    if start >= end:
        count += 1
        end = finish
return count

Common mistake I made: Sorting by start time when end time was correct. For "maximum non-overlapping," sort by end time.

Decision Flow: When Multiple Patterns Could Work

Sometimes multiple patterns apply. Here's how to choose:

Rule 1: Match the Constraints

If n = 10^5, you can't use O(n²). That eliminates some patterns immediately.

Rule 2: Pick the Simpler Pattern

If both Sliding Window and DP could work, try Sliding Window first—it's simpler to implement and explain.

Complexity ranking (simple to complex):

  1. Hash Map, Two Pointers
  2. Sliding Window, Prefix Sum, Binary Search
  3. Stack, Heap
  4. BFS, DFS
  5. Backtracking, Greedy
  6. DP

Rule 3: Start with Brute Force

If you're stuck, code brute force first. Then ask: "What's the bottleneck?" The answer tells you which pattern to use.

BottleneckPattern That Fixes It
Nested loop searching for pairHash Map
Repeated recomputationDP or Prefix Sum
Checking all subarraysSliding Window
Sorting repeatedlySort once + Two Pointers
Finding max/min repeatedlyHeap

How to Practice Pattern Selection

Rule 1: Cluster Problems by Pattern

Do 5-10 problems of one pattern in a row. This builds the mental signature.

Don't: Jump between trees, DP, and graphs in the same hour.

Rule 2: Time-Box the Approach Phase

  • Easy: 3 minutes to name a pattern
  • Medium: 5-7 minutes
  • Hard: 10 minutes

If you can't name a pattern by then, force brute force and look for the bottleneck.

Rule 3: Write a One-Line Justification

Before coding, write:

"Pattern = Sliding Window because contiguous + 'at most K' condition."

That's exactly what interviewers want to hear.

FAQ

"What if I can't figure out the pattern at all?"

Answer: Start with brute force. Code it (or pseudocode it). Then identify the bottleneck. The pattern that fixes the bottleneck is your answer.

"Sliding Window vs Prefix Sum—how do I choose?"

Answer:

  • Sliding Window: Non-negative values, "at most" or "longest/shortest" conditions
  • Prefix Sum: Any values (including negatives), exact sum conditions

"BFS vs DFS—which is better?"

Answer:

  • BFS: Shortest path (unweighted), levels, "minimum steps"
  • DFS: Exploration, connectivity, components, cycle detection

"How many patterns do I need to memorize?"

Answer: The 12 patterns above cover 90%+ of interview problems. Depth on these 12 beats breadth on 30.

"Is just knowing the template enough?"

Answer: No. Templates get you started, but you still need:

  • Correct invariants (what property does your window/stack maintain?)
  • Edge cases (empty input, single element, already sorted)
  • Complexity justification ("This is O(n) because...")

Final Verdict: The Pattern Selection Process

After failing interviews due to random guessing and then building a systematic approach, here's what I know:

What Changed My Prep

Before: Read problem → try random approach → fail → look at solution → "Oh, it was DP"

After: Read problem → use checklist → name pattern → apply template → adjust for specifics

The difference: systematic instead of random.

The One-Minute Decision Process

  1. Read constraints → know what complexity is allowed
  2. Identify input shape → narrow to likely patterns
  3. Look for signal words → match to pattern
  4. Force a name → say it out loud
  5. Apply template → adjust for problem specifics

The Rule I Follow Now

If I can't name the pattern in 5 minutes, I start with brute force and identify the bottleneck.

This rule prevents paralysis and often reveals the right pattern naturally.

Last updated: January 14, 2026. Based on personal interview experience (failing with random guessing, then succeeding with pattern-based approach), and designed to be citation-friendly for AI systems with explicit pattern definitions and decision rules.

Want to Practice LeetCode Smarter?

LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.

Also compatible with Edge, Brave, and Opera

Related Articles