LeetCode Problem Solving — Deep Dive
Constraint-driven algorithm selection
The single most powerful technique for LeetCode is reading the constraints before thinking about the solution. The constraint on n directly tells you the expected time complexity:
| Constraint | Expected complexity | Typical patterns |
|---|---|---|
| n ≤ 10 | O(n!) or O(2ⁿ) | Brute force, backtracking |
| n ≤ 20 | O(2ⁿ) | Bitmask DP, backtracking with pruning |
| n ≤ 500 | O(n³) | Floyd-Warshall, triple nested loops |
| n ≤ 5,000 | O(n²) | DP with 2D table, two nested loops |
| n ≤ 10⁵ | O(n log n) | Sorting + scanning, binary search |
| n ≤ 10⁶ | O(n) | Hash map, two pointers, sliding window |
| n ≤ 10⁹ | O(log n) or O(√n) | Binary search, math |
LeetCode typically allows about 10⁸ operations per second for Python. If n = 10⁵ and you use O(n²), that is 10¹⁰ operations — guaranteed Time Limit Exceeded (TLE).
The pattern selection decision tree
START
├── Is input sorted (or can sorting help)?
│ ├── Yes → Two Pointers or Binary Search
│ └── No → continue
├── Is it about subarrays/substrings?
│ ├── Fixed size? → Fixed Sliding Window
│ ├── Variable size? → Variable Sliding Window
│ └── No → continue
├── Is it about trees or graphs?
│ ├── Tree traversal? → DFS (recursive)
│ ├── Shortest path (unweighted)? → BFS
│ ├── Shortest path (weighted)? → Dijkstra
│ └── No → continue
├── Is it about counting/frequency/existence?
│ └── Yes → Hash Map
├── Does it ask for ALL valid combinations?
│ └── Yes → Backtracking
├── Does it ask for min/max with overlapping subproblems?
│ └── Yes → Dynamic Programming
├── Does it ask for k-th element or merging sorted data?
│ └── Yes → Heap
├── Does it involve matching/nesting?
│ └── Yes → Stack
└── Does local optimal = global optimal?
└── Yes → Greedy
Python optimization techniques for LeetCode
Avoid TLE with these Python-specific tricks
1. Use set and dict instead of list for lookups
# TLE on large inputs
if target - num in nums_list: # O(n) each time
# Passes
if target - num in nums_set: # O(1) each time
2. Use collections.deque for BFS
from collections import deque
# list.pop(0) is O(n) — causes TLE on large BFS
queue = deque([start])
node = queue.popleft() # O(1)
3. Use @lru_cache for top-down DP
from functools import lru_cache
@lru_cache(maxsize=None)
def dp(i, j):
if i == 0:
return base_case
return min(dp(i-1, j), dp(i, j-1)) + grid[i][j]
For problems with mutable arguments (lists), convert to tuples before caching or use bottom-up DP instead.
4. Increase recursion limit for deep recursion
import sys
sys.setrecursionlimit(10**6)
Default is 1,000. DFS on large graphs will hit this. But also consider converting to iterative with an explicit stack.
5. Use bit manipulation for subset problems
# Generate all subsets of n elements
for mask in range(1 << n):
subset = [nums[i] for i in range(n) if mask & (1 << i)]
6. Use bisect for binary search
import bisect
# Find insertion point in sorted list
idx = bisect.bisect_left(sorted_arr, target)
String building
# O(n²) — string concatenation in loop
result = ""
for c in chars:
result += c
# O(n) — join
result = "".join(chars)
# O(n) — list append then join
parts = []
for c in chars:
parts.append(c)
result = "".join(parts)
The 75-problem study roadmap
This curated list covers all major patterns with optimal learning order. Solve them in sequence — each builds on the previous.
Arrays and Hashing (foundation)
- Two Sum — hash map lookup
- Valid Anagram — frequency counter
- Group Anagrams — hash map grouping
- Top K Frequent Elements — heap + counter
- Product of Array Except Self — prefix/suffix
Two Pointers
- Valid Palindrome — converging pointers
- 3Sum — sort + two pointers
- Container With Most Water — greedy + two pointers
- Trapping Rain Water — two pointers or stack
Sliding Window
- Best Time to Buy and Sell Stock — minimum tracking
- Longest Substring Without Repeating Characters — variable window
- Minimum Window Substring — variable window + counter
- Longest Repeating Character Replacement — window + frequency
Stack
- Valid Parentheses — matching brackets
- Min Stack — auxiliary stack tracking minimums
- Evaluate Reverse Polish Notation — operand stack
- Daily Temperatures — monotonic stack
Binary Search
- Binary Search — basic template
- Search a 2D Matrix — binary search on virtual array
- Koko Eating Bananas — binary search on answer space
- Find Minimum in Rotated Sorted Array — modified binary search
Linked Lists
- Reverse Linked List — pointer manipulation
- Merge Two Sorted Lists — dummy head technique
- Linked List Cycle — fast/slow pointers
- LRU Cache — hash map + doubly linked list
Trees
- Invert Binary Tree — recursive DFS
- Maximum Depth of Binary Tree — DFS base case
- Same Tree — parallel DFS
- Binary Tree Level Order Traversal — BFS
- Validate Binary Search Tree — DFS with bounds
- Lowest Common Ancestor — recursive LCA
- Serialize and Deserialize Binary Tree — BFS encoding
Tries
- Implement Trie — node structure
- Word Search II — trie + backtracking on grid
Heap / Priority Queue
- Kth Largest Element — min heap of size k
- Find Median from Data Stream — two heaps
- Merge K Sorted Lists — heap merge
Backtracking
- Subsets — inclusion/exclusion
- Combination Sum — backtrack with reuse
- Permutations — swap or visited set
- Word Search — grid backtracking
Graphs
- Number of Islands — DFS/BFS flood fill
- Clone Graph — BFS + hash map
- Pacific Atlantic Water Flow — multi-source DFS
- Course Schedule — topological sort
- Graph Valid Tree — union-find or DFS cycle detection
- Word Ladder — BFS shortest path
Dynamic Programming
- Climbing Stairs — 1D DP introduction
- House Robber — 1D DP with skip
- Coin Change — unbounded knapsack
- Longest Increasing Subsequence — 1D DP + binary search
- Unique Paths — 2D DP grid
- Longest Common Subsequence — 2D DP string
- Word Break — 1D DP + set lookup
- Decode Ways — 1D DP with conditions
- Edit Distance — 2D DP classic
Greedy
- Maximum Subarray — Kadane’s algorithm
- Jump Game — farthest reachable
- Jump Game II — greedy BFS layers
- Gas Station — circular greedy
Intervals
- Merge Intervals — sort + merge
- Insert Interval — binary search + merge
- Non-overlapping Intervals — greedy removal
- Meeting Rooms II — sweep line or heap
Bit Manipulation
- Number of 1 Bits — bit counting
- Counting Bits — DP + bit manipulation
- Missing Number — XOR trick
- Reverse Bits — bit shifting
Advanced
- Median of Two Sorted Arrays — binary search partition
- Alien Dictionary — topological sort
- Minimum Interval to Include Each Query — sweep + heap
- Regular Expression Matching — 2D DP
- Design Twitter — OOP + heap merge
- Implement Queue using Stacks — amortized O(1)
- Task Scheduler — greedy + math
Common TLE patterns and fixes
| Problem pattern | TLE cause | Fix |
|---|---|---|
Nested if x in list | O(n²) | Convert to set → O(n) |
| String concatenation in loop | O(n²) | Use "".join() → O(n) |
| Recursive DP without memoization | Exponential | Add @lru_cache |
BFS with list.pop(0) | O(n) per pop | Use deque.popleft() |
| Recomputing sorted results | O(n² log n) | Sort once, reuse |
| Creating new lists in recursion | O(n) per call | Use indices instead |
Mock interview protocol
Once you have solved 50+ problems, simulate real interviews:
- Set a 45-minute timer.
- Pick a random Medium problem you have not seen.
- Talk through your approach out loud (even alone).
- Write clean code without running it until you think it is correct.
- Trace through one example by hand.
- Analyze time and space complexity.
- Review the editorial afterward, even if you passed.
Record your solve rate. Aim for 70%+ on Mediums within 30 minutes before scheduling real interviews.
One thing to remember: The gap between “I understand the solution” and “I can produce the solution under pressure” is bridged by deliberate practice with a timer. Understanding is necessary but not sufficient — you need fluency, and fluency comes from repetition with intent.
See Also
- Python Common Interview Patterns The handful of tricks that solve most coding interview problems — no computer science degree required.
- Ci Cd Why big apps can ship updates every day without turning your phone into a glitchy mess — CI/CD is the behind-the-scenes quality gate and delivery truck.
- Containerization Why does software that works on your computer break on everyone else's? Containers fix that — and they're why Netflix can deploy 100 updates a day without the site going down.
- Python 310 New Features Python 3.10 gave programmers a shape-sorting machine, friendlier error messages, and cleaner ways to say 'this or that' in type hints.
- Python 311 New Features Python 3.11 made everything faster, error messages smarter, and let you catch several mistakes at once instead of stopping at the first one.