How to Approach LeetCode Problems
Staring at a blank editor with a problem you don’t know how to solve is frustrating. But most people struggle not because the problems are impossibly hard — they struggle because they don’t have a systematic approach. Here’s a framework that works.
Step 1: Understand the Problem (Really)
Read the problem statement twice. Then answer these questions before touching your keyboard:
- What are the inputs? Types, ranges, edge cases (empty arrays, negative numbers, duplicates).
- What is the output? A single value? A list? A boolean?
- What are the constraints? The constraint size tells you what time complexity you need:
- n <= 20 → brute force or backtracking (O(2^n)) is fine
- n <= 1,000 → O(n^2) will work
- n <= 100,000 → you need O(n log n) or O(n)
- n <= 10,000,000 → O(n) or O(log n) only
Step 2: Work Through Examples by Hand
Take the sample inputs and trace through them manually. Don’t think about code yet — think about how you would solve it as a human.
This step is where insights happen. You might notice:
- “I keep comparing pairs” → maybe two pointers
- “I need to track what I’ve seen” → maybe a hash map
- “I’m looking at subarrays of varying length” → maybe sliding window
- “I need to try all combinations” → maybe backtracking
Step 3: Identify the Pattern
This is the most important step. Before writing code, name the pattern you’re going to use. Common ones include:
| Pattern | When to Use |
|---|---|
| Hash Map | Need O(1) lookups, counting, or tracking seen values |
| Two Pointers | Sorted array, finding pairs, or partitioning |
| Sliding Window | Contiguous subarray/substring with a constraint |
| Binary Search | Sorted data, or searching for a boundary |
| BFS/DFS | Graph traversal, tree problems, connected components |
| Dynamic Programming | Optimal substructure + overlapping subproblems |
| Stack | Matching brackets, monotonic sequences, undo operations |
If you can’t identify a pattern, that’s a signal to go back to Step 2 and work through more examples.
Step 4: Plan Before You Code
Write pseudocode or outline your approach in comments. Specify:
- What data structures you’ll use
- The main loop or recursion structure
- How you’ll handle edge cases
This takes 2 minutes and saves 20 minutes of debugging a half-baked solution.
Step 5: Implement and Verify
Now write the code. Keep it simple — don’t optimize prematurely.
After implementing, test with the examples from Step 2. Trace through your code with the inputs and verify the outputs match. Then think about edge cases:
- Empty input
- Single element
- All duplicates
- Already sorted / reverse sorted
- Maximum constraint values
The Meta-Strategy
The biggest mistake people make is jumping to code too quickly. The framework above front-loads the thinking so that by the time you’re writing code, you already know it’s going to work.
Over time, pattern recognition becomes automatic. You’ll read a problem and immediately think “this is a sliding window problem” or “this needs a monotonic stack.” That intuition comes from practice — but only if you practice deliberately, not just grinding problems randomly.
Focus on one pattern at a time. Solve 5-10 problems in that pattern before moving on. That’s more effective than solving 50 random problems.