- Published on
Coding Interview Pattern Mastery: 15 Algorithm Patterns + 75 Problems Roadmap for FAANG 2025
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. The State of Coding Interviews in 2025
- 2. Pattern 1 — Arrays and Hashing
- 3. Pattern 2 — Two Pointers
- 4. Pattern 3 — Sliding Window
- 5. Pattern 4 — Stack (Monotonic Stack)
- 6. Pattern 5 — Binary Search
- 7. Pattern 6 — Linked List
- 8. Pattern 7 — Trees (BFS/DFS)
- 9. Pattern 8 — Tries
- 10. Pattern 9 — Heap / Priority Queue
- 11. Pattern 10 — Backtracking
- 12. Pattern 11 — Graphs (BFS/DFS/Union-Find)
- 13. Pattern 12 — Dynamic Programming (1D)
- 14. Pattern 13 — Dynamic Programming (2D)
- 15. Pattern 14 — Greedy
- 16. Pattern 15 — Intervals and Math
- 17. 75-Problem Curated Checklist
- 18. Practical Interview Tips
- 19. Quiz
- 20. References
1. The State of Coding Interviews in 2025
FAANG Interview Frequency Data and Trends
In 2025, FAANG (Meta, Apple, Amazon, Netflix, Google) coding interviews have shifted toward pattern-based problem design. Rather than pure memorization, interviewers now prefer problems that combine or modify known patterns. Graph + DP hybrid questions and Sliding Window + Hash Map combinations appear frequently.
Here is a breakdown of pattern frequency by company in 2025:
| Pattern | Meta | Amazon | Apple | Microsoft | |
|---|---|---|---|---|---|
| Arrays/Hashing | 25% | 30% | 35% | 20% | 28% |
| Trees/Graphs | 22% | 18% | 15% | 25% | 20% |
| Dynamic Programming | 18% | 15% | 12% | 18% | 15% |
| Two Pointers/Sliding Window | 12% | 15% | 18% | 10% | 12% |
| Binary Search | 8% | 7% | 8% | 10% | 10% |
| Other (Stack, Heap, Trie, etc.) | 15% | 15% | 12% | 17% | 15% |
The Rise of AI-Aware Coding Rounds
Starting in 2025, some companies have introduced AI copilot-aware coding interviews. These focus less on raw implementation and more on problem analysis, optimal algorithm selection, and code review skills. However, traditional whiteboard coding remains the norm, and understanding algorithm patterns is still essential.
NeetCode 150 vs Blind 75 vs Grind 75
| Feature | Blind 75 | NeetCode 150 | Grind 75 |
|---|---|---|---|
| Problem Count | 75 | 150 | 75 (customizable) |
| Difficulty Spread | Easy 20%, Medium 55%, Hard 25% | Easy 25%, Medium 50%, Hard 25% | Easy 25%, Medium 55%, Hard 20% |
| Pattern Coverage | 13 | 15 | 14 |
| Last Updated | 2021 | 2024 | 2023 |
| Best For | Experienced devs with limited time | Systematic learners | Custom schedule seekers |
This article selects 75 essential problems from NeetCode 150, organized by pattern.
Language Choice: Python vs Java vs TypeScript
- Python: Concise syntax and fast prototyping. Most popular language at FAANG interviews. Powerful built-in libraries (heapq, collections, itertools)
- Java: Type safety and performance advantages. Preferred at Amazon and Google. Rich data structures (TreeMap, PriorityQueue)
- TypeScript: Advantageous for frontend roles. However, it offers fewer advantages for algorithm problems compared to Python
All code examples in this article use Python.
12-Week Study Roadmap Overview
| Week | Patterns | Daily Problems |
|---|---|---|
| 1-2 | Arrays/Hashing, Two Pointers | 2 problems |
| 3-4 | Sliding Window, Stack, Binary Search | 2 problems |
| 5-6 | Linked List, Trees | 2 problems |
| 7-8 | Tries, Heap, Backtracking | 2 problems |
| 9-10 | Graphs, 1D DP | 2-3 problems |
| 11-12 | 2D DP, Greedy, Intervals, Review | 2-3 problems |
2. Pattern 1 — Arrays and Hashing
Core Idea
Arrays and hash maps are the foundation of all algorithms. The key technique is using hash map O(1) lookups to reduce brute force O(n^2) to O(n). Essential for frequency counting, duplicate detection, and grouping problems.
Time/Space Complexity
- Hash map insert/lookup: O(1) average, O(n) worst case
- Sort-based approach: O(n log n)
- Space: O(n) for hash map storage
Representative Problems
- Two Sum (LeetCode 1) — Easy
- Contains Duplicate (LeetCode 217) — Easy
- Valid Anagram (LeetCode 242) — Easy
- Group Anagrams (LeetCode 49) — Medium
- Top K Frequent Elements (LeetCode 347) — Medium
Python Solution — Two Sum (LeetCode 1)
def twoSum(nums: list[int], target: int) -> list[int]:
# Hash map: value -> index mapping
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
# Time: O(n), Space: O(n)
# Key insight: Look up complement in hash map in O(1)
Variations and Tips
- Three Sum (LeetCode 15): Sort first, then combine with Two Pointers
- Product of Array Except Self (LeetCode 238): Prefix/suffix product pattern
- Interview tip: Always check if a hash map can provide an O(n) solution first
3. Pattern 2 — Two Pointers
Core Idea
On sorted arrays or strings, use two pointers moving inward from both ends to find pairs that meet a condition. Alternatively, use fast/slow pointers moving in the same direction. Optimizes O(n^2) brute force to O(n).
Time/Space Complexity
- Time: O(n) (if already sorted) or O(n log n) (if sorting needed)
- Space: O(1) — no extra space required
Representative Problems
- Valid Palindrome (LeetCode 125) — Easy
- Two Sum II - Sorted Array (LeetCode 167) — Medium
- 3Sum (LeetCode 15) — Medium
- Container With Most Water (LeetCode 11) — Medium
- Trapping Rain Water (LeetCode 42) — Hard
Python Solution — Container With Most Water (LeetCode 11)
def maxArea(height: list[int]) -> int:
left, right = 0, len(height) - 1
max_water = 0
while left < right:
# Calculate water area with current two walls
width = right - left
h = min(height[left], height[right])
max_water = max(max_water, width * h)
# Move the shorter wall's pointer inward
if height[left] < height[right]:
left += 1
else:
right -= 1
return max_water
# Time: O(n), Space: O(1)
# Key insight: Moving the shorter wall is the only way to potentially increase area
Variations and Tips
- Trapping Rain Water: Track maximum heights from both sides
- Interview tip: If the input is sorted, consider Two Pointers first
- For 3Sum, fix one element and use Two Pointers on the remaining
4. Pattern 3 — Sliding Window
Core Idea
Slide a fixed or variable-size window across an array or string to find optimal values (maximum sum, minimum length, valid substrings). Add new elements and remove old ones while maintaining O(n) time.
Time/Space Complexity
- Time: O(n) — each element enters and leaves the window at most once
- Space: O(k) — window size or character set size
Representative Problems
- Best Time to Buy and Sell Stock (LeetCode 121) — Easy
- Longest Substring Without Repeating Characters (LeetCode 3) — Medium
- Longest Repeating Character Replacement (LeetCode 424) — Medium
- Minimum Window Substring (LeetCode 76) — Hard
- Sliding Window Maximum (LeetCode 239) — Hard
Python Solution — Longest Substring Without Repeating Characters (LeetCode 3)
def lengthOfLongestSubstring(s: str) -> int:
char_index = {} # char -> last seen index
left = 0
max_len = 0
for right in range(len(s)):
if s[right] in char_index and char_index[s[right]] >= left:
# Duplicate found: move left past the duplicate
left = char_index[s[right]] + 1
char_index[s[right]] = right
max_len = max(max_len, right - left + 1)
return max_len
# Time: O(n), Space: O(min(n, 26))
# Key insight: Track duplicate positions with hash map, update window size
Variations and Tips
- Minimum Window Substring: Track required character counts with a hash map while shrinking
- Fixed-size window: Maintain right - left + 1 == k
- Interview tip: If the problem involves contiguous subarrays or substrings, consider Sliding Window
5. Pattern 4 — Stack (Monotonic Stack)
Core Idea
Leverage the LIFO (Last In First Out) property. Use basic stacks for parentheses matching and expression evaluation. Use Monotonic Stacks for Next Greater/Smaller Element problems — the stack maintains elements in strictly increasing or decreasing order.
Time/Space Complexity
- Time: O(n) — each element is pushed and popped at most once
- Space: O(n) — stack storage
Representative Problems
- Valid Parentheses (LeetCode 20) — Easy
- Min Stack (LeetCode 155) — Medium
- Evaluate Reverse Polish Notation (LeetCode 150) — Medium
- Daily Temperatures (LeetCode 739) — Medium
- Largest Rectangle in Histogram (LeetCode 84) — Hard
Python Solution — Daily Temperatures (LeetCode 739)
def dailyTemperatures(temperatures: list[int]) -> list[int]:
n = len(temperatures)
answer = [0] * n
stack = [] # Monotonic decreasing stack: stores indices
for i in range(n):
# Pop while current temp is higher than stack top
while stack and temperatures[i] > temperatures[stack[-1]]:
prev_idx = stack.pop()
answer[prev_idx] = i - prev_idx
stack.append(i)
return answer
# Time: O(n), Space: O(n)
# Key insight: Monotonic decreasing stack computes distance to next greater element in O(n)
Variations and Tips
- Largest Rectangle in Histogram: Monotonic increasing stack to compute max width per height
- Next Greater Element: For circular arrays, iterate 2n times
- Interview tip: When the relationship between current and previous elements matters, think monotonic stack
6. Pattern 5 — Binary Search
Core Idea
Halve the search space in sorted data to find answers in O(log n). Beyond array searching, it also applies to decision problems — converting optimization problems to binary search. Classic patterns include "maximize the minimum" or "minimize the maximum."
Time/Space Complexity
- Time: O(log n)
- Space: O(1) iterative / O(log n) recursive
Representative Problems
- Binary Search (LeetCode 704) — Easy
- Search a 2D Matrix (LeetCode 74) — Medium
- Koko Eating Bananas (LeetCode 875) — Medium
- Find Minimum in Rotated Sorted Array (LeetCode 153) — Medium
- Median of Two Sorted Arrays (LeetCode 4) — Hard
Python Solution — Koko Eating Bananas (LeetCode 875)
import math
def minEatingSpeed(piles: list[int], h: int) -> int:
# Binary search on speed range [1, max(piles)]
left, right = 1, max(piles)
while left < right:
mid = (left + right) // 2
# Check if Koko can eat all bananas at speed mid within h hours
hours_needed = sum(math.ceil(pile / mid) for pile in piles)
if hours_needed <= h:
right = mid # Try a slower speed
else:
left = mid + 1 # Need a faster speed
return left
# Time: O(n * log(max(piles))), Space: O(1)
# Key insight: Binary search on the answer for a decision problem
Variations and Tips
- Rotated Sorted Array: Compare mid with endpoints to identify the sorted half
- Decision problem pattern: If canDo(x) is monotonic, binary search applies
- Interview tip: Even if the data is not sorted, if the answer range is monotonic, consider binary search
7. Pattern 6 — Linked List
Core Idea
Linked list problems revolve around pointer manipulation. Reversal, merging, cycle detection, and finding the middle node are recurring themes. The fast/slow pointer technique (Floyd's algorithm) is essential for cycle detection and middle node finding.
Time/Space Complexity
- Traversal: O(n) time, O(1) space
- Recursive approaches: O(n) time, O(n) stack space
Representative Problems
- Reverse Linked List (LeetCode 206) — Easy
- Merge Two Sorted Lists (LeetCode 21) — Easy
- Linked List Cycle (LeetCode 141) — Easy
- Reorder List (LeetCode 143) — Medium
- Merge k Sorted Lists (LeetCode 23) — Hard
Python Solution — Reverse Linked List (LeetCode 206)
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverseList(head: ListNode) -> ListNode:
prev = None
current = head
while current:
next_node = current.next # Save next node
current.next = prev # Reverse the link
prev = current # Advance prev
current = next_node # Advance current
return prev
# Time: O(n), Space: O(1)
# Key insight: Three pointers (prev, current, next) for in-place reversal
Variations and Tips
- Reorder List: Find middle + reverse second half + merge — 3 steps
- Merge k Sorted Lists: Use a min-heap to manage k list heads
- Interview tip: Using a dummy node simplifies edge case handling
8. Pattern 7 — Trees (BFS/DFS)
Core Idea
Tree problems split into recursive DFS (preorder/inorder/postorder) and BFS (level-order). Most binary tree problems can be solved by defining "what to do at the current node, and what to delegate to children."
Time/Space Complexity
- DFS: O(n) time, O(h) space (h = tree height, worst case O(n))
- BFS: O(n) time, O(w) space (w = maximum level width)
Representative Problems
- Maximum Depth of Binary Tree (LeetCode 104) — Easy
- Invert Binary Tree (LeetCode 226) — Easy
- Binary Tree Level Order Traversal (LeetCode 102) — Medium
- Validate Binary Search Tree (LeetCode 98) — Medium
- Binary Tree Maximum Path Sum (LeetCode 124) — Hard
Python Solution — Binary Tree Level Order Traversal (LeetCode 102)
from collections import deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def levelOrder(root: TreeNode) -> list[list[int]]:
if not root:
return []
result = []
queue = deque([root])
while queue:
level_size = len(queue)
level = []
for _ in range(level_size):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(level)
return result
# Time: O(n), Space: O(n)
# Key insight: Process level_size nodes per iteration to group by level
Variations and Tips
- BST Validation: Check inorder traversal is sorted, or pass value ranges via DFS
- Maximum Path Sum: Postorder traversal computing max contribution from children
- Interview tip: Always handle the base case (null node) first in tree problems
9. Pattern 8 — Tries
Core Idea
A Trie (Prefix Tree) stores strings character by character in a tree structure. Prefix searches take O(m) where m is the string length. Useful for autocomplete, dictionary lookup, and wildcard matching.
Time/Space Complexity
- Insert/Search: O(m) — m is the string length
- Space: O(total characters * alphabet size)
Representative Problems
- Implement Trie (Prefix Tree) (LeetCode 208) — Medium
- Design Add and Search Words (LeetCode 211) — Medium
- Word Search II (LeetCode 212) — Hard
Python Solution — Implement Trie (LeetCode 208)
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word: str) -> None:
node = self.root
for ch in word:
if ch not in node.children:
node.children[ch] = TrieNode()
node = node.children[ch]
node.is_end = True
def search(self, word: str) -> bool:
node = self._find(word)
return node is not None and node.is_end
def startsWith(self, prefix: str) -> bool:
return self._find(prefix) is not None
def _find(self, prefix: str) -> TrieNode:
node = self.root
for ch in prefix:
if ch not in node.children:
return None
node = node.children[ch]
return node
# Time: Insert/Search O(m), Space: O(total characters)
# Key insight: Each node holds a children dict and an end-of-word flag
Variations and Tips
- Word Search II: Trie + DFS backtracking combination
- Design Add and Search Words: Recursive DFS for wildcard
. - Interview tip: When you need repeated prefix lookups across multiple strings, Trie is efficient
10. Pattern 9 — Heap / Priority Queue
Core Idea
A Heap provides O(1) max/min access with O(log n) insert/delete. Essential for Top K problems, streaming median, and task scheduling.
Time/Space Complexity
- Insert/Delete: O(log n)
- Max/Min access: O(1)
- Heapify: O(n)
Representative Problems
- Kth Largest Element in a Stream (LeetCode 703) — Easy
- Last Stone Weight (LeetCode 1046) — Easy
- K Closest Points to Origin (LeetCode 973) — Medium
- Task Scheduler (LeetCode 621) — Medium
- Find Median from Data Stream (LeetCode 295) — Hard
Python Solution — Find Median from Data Stream (LeetCode 295)
import heapq
class MedianFinder:
def __init__(self):
# max_heap: lower half (store negatives for max heap in Python)
# min_heap: upper half
self.max_heap = [] # left half
self.min_heap = [] # right half
def addNum(self, num: int) -> None:
# Always push to max_heap first
heapq.heappush(self.max_heap, -num)
# Move max of max_heap to min_heap
heapq.heappush(self.min_heap, -heapq.heappop(self.max_heap))
# Balance: max_heap should be >= min_heap in size
if len(self.min_heap) > len(self.max_heap):
heapq.heappush(self.max_heap, -heapq.heappop(self.min_heap))
def findMedian(self) -> float:
if len(self.max_heap) > len(self.min_heap):
return -self.max_heap[0]
return (-self.max_heap[0] + self.min_heap[0]) / 2
# Time: addNum O(log n), findMedian O(1)
# Key insight: Two heaps split data in half to efficiently maintain the median
Variations and Tips
- Task Scheduler: Max heap to schedule the most frequent task first
- Python heapq is a min heap; negate values for max heap behavior
- Interview tip: Top K problems can be solved in O(n log k) with a size-K min heap
11. Pattern 10 — Backtracking
Core Idea
Explore all possible combinations, permutations, and subsets while pruning invalid paths early. The pattern is recursion + choose/unchoose. Since time complexity is exponential, pruning is critical for performance.
Time/Space Complexity
- Subsets: O(2^n)
- Permutations: O(n!)
- Space: O(n) — recursion depth
Representative Problems
- Subsets (LeetCode 78) — Medium
- Combination Sum (LeetCode 39) — Medium
- Permutations (LeetCode 46) — Medium
- Word Search (LeetCode 79) — Medium
- N-Queens (LeetCode 51) — Hard
Python Solution — Combination Sum (LeetCode 39)
def combinationSum(candidates: list[int], target: int) -> list[list[int]]:
result = []
def backtrack(start: int, current: list[int], remaining: int):
if remaining == 0:
result.append(current[:]) # Add current combination to results
return
if remaining < 0:
return # Pruning
for i in range(start, len(candidates)):
current.append(candidates[i])
# Same element can be reused -> keep start at i
backtrack(i, current, remaining - candidates[i])
current.pop() # Unchoose (backtrack)
backtrack(0, [], target)
return result
# Time: O(2^t) (t = target / min(candidates)), Space: O(target)
# Key insight: Choose -> recurse -> unchoose pattern with pruning
Variations and Tips
- Subsets: Add current state to results at every step
- Permutations: Use a visited array or swap technique
- N-Queens: Track row/column/diagonal conflicts with sets
- Interview tip: Drawing the decision tree helps visualize backtracking patterns
12. Pattern 11 — Graphs (BFS/DFS/Union-Find)
Core Idea
Graph problems fall into connected components, shortest paths, cycle detection, and topological sort. BFS for shortest paths, DFS for path exploration and cycle detection, and Union-Find for connected component management.
Time/Space Complexity
- BFS/DFS: O(V + E) time, O(V) space
- Union-Find: O(alpha(n)) almost O(1) per operation
- Topological Sort: O(V + E)
Representative Problems
- Number of Islands (LeetCode 200) — Medium
- Clone Graph (LeetCode 133) — Medium
- Course Schedule (LeetCode 207) — Medium (Topological Sort)
- Pacific Atlantic Water Flow (LeetCode 417) — Medium
- Graph Valid Tree (LeetCode 261) — Medium (Union-Find)
Python Solution — Number of Islands (LeetCode 200)
def numIslands(grid: list[list[str]]) -> int:
if not grid:
return 0
rows, cols = len(grid), len(grid[0])
count = 0
def dfs(r: int, c: int):
# Out of bounds or water -> return
if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] == '0':
return
grid[r][c] = '0' # Mark as visited
# Explore 4 directions
dfs(r + 1, c)
dfs(r - 1, c)
dfs(r, c + 1)
dfs(r, c - 1)
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
count += 1
dfs(r, c)
return count
# Time: O(m * n), Space: O(m * n) worst case recursion depth
# Key insight: DFS flood-fill to mark entire island when a new '1' is found
Union-Find Implementation
class UnionFind:
def __init__(self, n: int):
self.parent = list(range(n))
self.rank = [0] * n
self.count = n # Number of connected components
def find(self, x: int) -> int:
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # Path compression
return self.parent[x]
def union(self, x: int, y: int) -> bool:
px, py = self.find(x), self.find(y)
if px == py:
return False
# Union by rank
if self.rank[px] < self.rank[py]:
px, py = py, px
self.parent[py] = px
if self.rank[px] == self.rank[py]:
self.rank[px] += 1
self.count -= 1
return True
Variations and Tips
- Course Schedule: Topological sort (Kahn's algorithm) for cycle detection
- Pacific Atlantic Water Flow: Reverse BFS — start from ocean and move inland
- Interview tip: First decide on adjacency list vs matrix representation, then choose BFS/DFS/Union-Find
13. Pattern 12 — Dynamic Programming (1D)
Core Idea
1D DP uses a single variable's optimal substructure. Define a recurrence dp[i] and compute the current state from previous states (dp[i-1], dp[i-2], etc.). Fibonacci, stair climbing, and house robber are classic examples.
Time/Space Complexity
- Time: O(n) to O(n * k)
- Space: O(n) (tabulation) or O(1) (space-optimized)
Representative Problems
- Climbing Stairs (LeetCode 70) — Easy
- House Robber (LeetCode 198) — Medium
- Coin Change (LeetCode 322) — Medium
- Longest Increasing Subsequence (LeetCode 300) — Medium
- Word Break (LeetCode 139) — Medium
Python Solution — Coin Change (LeetCode 322)
def coinChange(coins: list[int], amount: int) -> int:
# dp[i] = minimum coins to make amount i
dp = [float('inf')] * (amount + 1)
dp[0] = 0 # 0 amount needs 0 coins
for i in range(1, amount + 1):
for coin in coins:
if coin <= i and dp[i - coin] != float('inf'):
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
# Time: O(amount * len(coins)), Space: O(amount)
# Key insight: Try every coin for each amount, taking the minimum
Variations and Tips
- House Robber: dp[i] = max(dp[i-1], dp[i-2] + nums[i]) — no adjacent houses
- LIS: O(n log n) solution uses binary search with an auxiliary array
- Word Break: dp[i] = any j where dp[j] and s[j:i] in wordSet
- Interview tip: Many 1D DP problems can be space-optimized to O(1), so mention this
14. Pattern 13 — Dynamic Programming (2D)
Core Idea
2D DP defines states over two variables (two strings, grid coordinates, etc.). dp[i][j] represents the result considering the first i elements of input 1 and the first j elements of input 2.
Time/Space Complexity
- Time: O(m * n)
- Space: O(m * n) or O(min(m, n)) with row compression
Representative Problems
- Unique Paths (LeetCode 62) — Medium
- Longest Common Subsequence (LeetCode 1143) — Medium
- Best Time to Buy and Sell Stock with Cooldown (LeetCode 309) — Medium
- Target Sum (LeetCode 494) — Medium
- Edit Distance (LeetCode 72) — Medium
Python Solution — Longest Common Subsequence (LeetCode 1143)
def longestCommonSubsequence(text1: str, text2: str) -> int:
m, n = len(text1), len(text2)
# dp[i][j] = LCS length of first i chars of text1 and first j chars of text2
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if text1[i - 1] == text2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[m][n]
# Time: O(m * n), Space: O(m * n)
# Key insight: Same char -> diagonal + 1, different -> max of top/left
Variations and Tips
- Edit Distance: Consider insert/delete/replace — three operations
- Target Sum: Transform into a knapsack problem
- Space optimization: If only the previous row is needed, compress to a 1D array
- Interview tip: Clearly define the 2D DP recurrence before coding
15. Pattern 14 — Greedy
Core Idea
Apply locally optimal choices at each step that guarantee globally optimal results. Unlike DP, greedy never reverses previous choices. The challenge is identifying the correct greedy strategy. When proofs are difficult, memorizing patterns is efficient.
Time/Space Complexity
- Usually O(n) or O(n log n) when sorting is needed
- Space: O(1) to O(n)
Representative Problems
- Maximum Subarray (LeetCode 53) — Medium
- Jump Game (LeetCode 55) — Medium
- Jump Game II (LeetCode 45) — Medium
- Gas Station (LeetCode 134) — Medium
- Hand of Straights (LeetCode 846) — Medium
Python Solution — Jump Game (LeetCode 55)
def canJump(nums: list[int]) -> bool:
# goal: position we need to reach (work backward)
goal = len(nums) - 1
for i in range(len(nums) - 2, -1, -1):
if i + nums[i] >= goal:
goal = i # Current position can reach goal, so update goal
return goal == 0
# Time: O(n), Space: O(1)
# Key insight: Greedily check reachability from back to front
Variations and Tips
- Maximum Subarray (Kadane's): Reset running sum to 0 when it goes negative
- Jump Game II: BFS-style level counting for minimum jumps
- Interview tip: If unsure whether greedy is correct, test with small counterexamples
16. Pattern 15 — Intervals and Math
Core Idea
Interval problems revolve around sorting by start or end points, then handling overlaps. Merging, inserting, and minimum meeting rooms are classic examples. Math problems include bit manipulation, modular arithmetic, and geometric calculations.
Time/Space Complexity
- Sorting: O(n log n)
- Scanning: O(n)
- Space: O(n) for result storage
Representative Problems
- Merge Intervals (LeetCode 56) — Medium
- Insert Interval (LeetCode 57) — Medium
- Non-overlapping Intervals (LeetCode 435) — Medium
- Meeting Rooms II (LeetCode 253) — Medium
- Rotate Image (LeetCode 48) — Medium
Python Solution — Merge Intervals (LeetCode 56)
def merge(intervals: list[list[int]]) -> list[list[int]]:
# Sort by start point
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for start, end in intervals[1:]:
# If current interval overlaps with the last merged one
if start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return merged
# Time: O(n log n), Space: O(n)
# Key insight: Sort, then sequentially merge overlapping intervals
Variations and Tips
- Meeting Rooms II: Separate and sort start/end times, then count overlaps
- Non-overlapping Intervals: Sort by end time, then greedily remove minimal intervals
- Rotate Image: Transpose then reverse each row
- Interview tip: For interval problems, first decide the sort key (start vs end)
17. 75-Problem Curated Checklist
Below is a curated 75-problem checklist based on NeetCode 150.
| # | Problem | Difficulty | Pattern | Frequently Asked At |
|---|---|---|---|---|
| 1 | Two Sum (1) | Easy | Arrays/Hashing | Google, Amazon, Meta |
| 2 | Contains Duplicate (217) | Easy | Arrays/Hashing | Amazon, Apple |
| 3 | Valid Anagram (242) | Easy | Arrays/Hashing | Meta, Microsoft |
| 4 | Group Anagrams (49) | Medium | Arrays/Hashing | Amazon, Google |
| 5 | Top K Frequent Elements (347) | Medium | Arrays/Hashing | Amazon, Meta |
| 6 | Valid Palindrome (125) | Easy | Two Pointers | Meta, Microsoft |
| 7 | Two Sum II (167) | Medium | Two Pointers | Amazon, Google |
| 8 | 3Sum (15) | Medium | Two Pointers | Meta, Google, Amazon |
| 9 | Container With Most Water (11) | Medium | Two Pointers | Amazon, Google |
| 10 | Trapping Rain Water (42) | Hard | Two Pointers | Google, Amazon, Meta |
| 11 | Best Time to Buy and Sell Stock (121) | Easy | Sliding Window | Amazon, Meta |
| 12 | Longest Substring Without Repeating (3) | Medium | Sliding Window | Amazon, Google, Meta |
| 13 | Longest Repeating Character Replacement (424) | Medium | Sliding Window | Google, Microsoft |
| 14 | Minimum Window Substring (76) | Hard | Sliding Window | Meta, Google, Amazon |
| 15 | Valid Parentheses (20) | Easy | Stack | Amazon, Meta |
| 16 | Min Stack (155) | Medium | Stack | Amazon, Google |
| 17 | Evaluate Reverse Polish Notation (150) | Medium | Stack | Amazon, Microsoft |
| 18 | Daily Temperatures (739) | Medium | Stack (Monotonic) | Google, Amazon |
| 19 | Largest Rectangle in Histogram (84) | Hard | Stack (Monotonic) | Google, Amazon |
| 20 | Binary Search (704) | Easy | Binary Search | Google, Microsoft |
| 21 | Search a 2D Matrix (74) | Medium | Binary Search | Amazon, Microsoft |
| 22 | Koko Eating Bananas (875) | Medium | Binary Search | Google, Amazon |
| 23 | Find Min in Rotated Sorted Array (153) | Medium | Binary Search | Meta, Amazon |
| 24 | Search in Rotated Sorted Array (33) | Medium | Binary Search | Meta, Google, Amazon |
| 25 | Reverse Linked List (206) | Easy | Linked List | Amazon, Microsoft |
| 26 | Merge Two Sorted Lists (21) | Easy | Linked List | Amazon, Meta |
| 27 | Linked List Cycle (141) | Easy | Linked List | Amazon, Microsoft |
| 28 | Reorder List (143) | Medium | Linked List | Meta, Amazon |
| 29 | Merge k Sorted Lists (23) | Hard | Linked List / Heap | Amazon, Google |
| 30 | Invert Binary Tree (226) | Easy | Trees | Google, Amazon |
| 31 | Maximum Depth of Binary Tree (104) | Easy | Trees | Amazon, Meta |
| 32 | Binary Tree Level Order Traversal (102) | Medium | Trees (BFS) | Amazon, Meta |
| 33 | Validate Binary Search Tree (98) | Medium | Trees (DFS) | Amazon, Meta |
| 34 | Binary Tree Maximum Path Sum (124) | Hard | Trees (DFS) | Meta, Google |
| 35 | Lowest Common Ancestor (236) | Medium | Trees (DFS) | Meta, Amazon, Google |
| 36 | Implement Trie (208) | Medium | Tries | Amazon, Google |
| 37 | Design Add and Search Words (211) | Medium | Tries | Meta, Amazon |
| 38 | Word Search II (212) | Hard | Tries + Backtracking | Amazon, Google |
| 39 | Kth Largest Element in Stream (703) | Easy | Heap | Amazon, Meta |
| 40 | Last Stone Weight (1046) | Easy | Heap | Google, Amazon |
| 41 | K Closest Points to Origin (973) | Medium | Heap | Amazon, Meta |
| 42 | Task Scheduler (621) | Medium | Heap | Meta, Amazon |
| 43 | Find Median from Data Stream (295) | Hard | Heap | Amazon, Google |
| 44 | Subsets (78) | Medium | Backtracking | Meta, Amazon |
| 45 | Combination Sum (39) | Medium | Backtracking | Amazon, Google |
| 46 | Permutations (46) | Medium | Backtracking | Meta, Amazon |
| 47 | Word Search (79) | Medium | Backtracking | Amazon, Meta |
| 48 | N-Queens (51) | Hard | Backtracking | Google, Amazon |
| 49 | Number of Islands (200) | Medium | Graphs (DFS) | Amazon, Google, Meta |
| 50 | Clone Graph (133) | Medium | Graphs (BFS/DFS) | Meta, Amazon |
| 51 | Course Schedule (207) | Medium | Graphs (Topological) | Amazon, Google |
| 52 | Pacific Atlantic Water Flow (417) | Medium | Graphs (DFS) | Google, Amazon |
| 53 | Number of Connected Components (323) | Medium | Graphs (Union-Find) | Google, Meta |
| 54 | Graph Valid Tree (261) | Medium | Graphs (Union-Find) | Google, Meta |
| 55 | Climbing Stairs (70) | Easy | DP (1D) | Amazon, Google |
| 56 | House Robber (198) | Medium | DP (1D) | Amazon, Google |
| 57 | House Robber II (213) | Medium | DP (1D) | Amazon, Google |
| 58 | Coin Change (322) | Medium | DP (1D) | Amazon, Google, Meta |
| 59 | Longest Increasing Subsequence (300) | Medium | DP (1D) | Google, Amazon |
| 60 | Word Break (139) | Medium | DP (1D) | Meta, Amazon, Google |
| 61 | Unique Paths (62) | Medium | DP (2D) | Amazon, Google |
| 62 | Longest Common Subsequence (1143) | Medium | DP (2D) | Google, Amazon |
| 63 | Best Time Buy/Sell Stock Cooldown (309) | Medium | DP (2D) | Amazon, Google |
| 64 | Target Sum (494) | Medium | DP (2D) | Meta, Google |
| 65 | Edit Distance (72) | Medium | DP (2D) | Google, Amazon |
| 66 | Maximum Subarray (53) | Medium | Greedy | Amazon, Google, Meta |
| 67 | Jump Game (55) | Medium | Greedy | Amazon, Google |
| 68 | Jump Game II (45) | Medium | Greedy | Amazon, Google |
| 69 | Gas Station (134) | Medium | Greedy | Amazon, Google |
| 70 | Hand of Straights (846) | Medium | Greedy | Google, Amazon |
| 71 | Merge Intervals (56) | Medium | Intervals | Google, Meta, Amazon |
| 72 | Insert Interval (57) | Medium | Intervals | Google, Meta |
| 73 | Non-overlapping Intervals (435) | Medium | Intervals | Google, Amazon |
| 74 | Meeting Rooms II (253) | Medium | Intervals | Google, Meta, Amazon |
| 75 | Rotate Image (48) | Medium | Math/Matrix | Amazon, Microsoft |
18. Practical Interview Tips
45-Minute Time Allocation
| Phase | Time | Activity |
|---|---|---|
| Understand | 5 min | Clarify requirements, review examples, ask questions |
| Approach | 10 min | Mention brute force, then explain optimal solution |
| Code | 20 min | Write clean code |
| Test | 5 min | Walk through examples, check edge cases |
| Q and A | 5 min | Complexity analysis, optimization discussion |
The UMPIRE Method
A systematic framework for solving coding interview problems.
- U - Understand: Fully understand the problem. Confirm examples, ask clarifying questions.
- M - Match: Match to known patterns. Identify which of these 15 patterns applies.
- P - Plan: Create a concrete plan. Write pseudocode.
- I - Implement: Code cleanly following the plan.
- R - Review: Review code line by line to catch bugs.
- E - Evaluate: Analyze time/space complexity. Discuss possible optimizations.
Edge Case Checklist
Commonly missed edge cases during interviews:
- Empty input (empty array, empty string, null/None)
- Single-element input
- All elements identical
- Negative values present
- Very large input (overflow check)
- Unsorted input (never assume sorted unless stated)
- Duplicate elements present
How AI Copilots Are Changing Interviews
Notable changes in 2025 coding interviews:
- Increased System Design Weight: Since AI can assist coding, architecture design skills matter more
- Code Review Assessment: More problems asking you to find bugs and performance issues in given code
- More Variations: Modified conditions on classic problems so memorized solutions fail
- Live Collaboration: More pair programming-style interviews with the interviewer
- Algorithm + System Design Hybrids: Discussing algorithm optimization at the system level
19. Quiz
Test your understanding of the material covered.
Q1. What is the time complexity of solving Two Sum with a hash map?
Answer: O(n)
We iterate through the array once, checking for each element whether the complement (target - num) exists in the hash map in O(1). Total time complexity is O(n), space complexity is also O(n). A significant improvement over brute force O(n^2).
Q2. What characteristics make a problem suitable for the Sliding Window pattern?
Answer: Finding optimal values in contiguous subarrays or substrings
Sliding Window applies to problems seeking maximum, minimum, or condition-satisfying lengths in contiguous portions of arrays or strings. The key word is "contiguous." Since each element enters and leaves the window at most once, the time complexity is O(n).
Q3. What type of problems is the Monotonic Stack used for?
Answer: Next Greater Element / Next Smaller Element type problems
Monotonic Stack finds the next larger (or smaller) element for each element. By maintaining elements in strictly increasing or decreasing order, it computes Next Greater/Smaller for all elements in O(n). Daily Temperatures and Largest Rectangle in Histogram are classic examples.
Q4. What is the time complexity per operation when Union-Find uses both path compression and union by rank?
Answer: Nearly O(1) — technically O(alpha(n))
alpha(n) is the inverse Ackermann function, which is effectively 5 or less for all practical inputs. Path compression flattens the tree during find by pointing nodes directly to the root. Union by rank attaches the shorter tree under the taller one. Together, they achieve amortized near-constant time operations.
Q5. List the 6 steps of the UMPIRE method in order.
Answer: Understand, Match, Plan, Implement, Review, Evaluate
- Understand: Fully understand the problem and ask clarifying questions
- Match: Match to known algorithm patterns
- Plan: Create a concrete plan and write pseudocode
- Implement: Code cleanly following the plan
- Review: Review code and find bugs
- Evaluate: Analyze time/space complexity
20. References
- NeetCode 150 Roadmap — Systematic pattern-based problem classification
- Blind 75 Problem List — The original curated list
- Grind 75 by Yangshun — Customizable scheduling
- LeetCode — Online coding practice platform
- Introduction to Algorithms (CLRS) — The algorithm bible
- Grokking the Coding Interview — Pattern-based learning
- Tech Interview Handbook — Comprehensive interview guide
- Competitive Programmer's Handbook (Antti Laaksonen) — Free algorithm textbook
- VisuAlgo — Algorithm visualization tool
- Big-O Cheat Sheet — Time/space complexity reference
- Python collections docs — Counter, deque, defaultdict
- Python heapq docs — Heap operations
- Back to Back SWE (YouTube) — Algorithm explanations
- Abdul Bari Algorithms (YouTube) — Algorithm lectures
- System Design Interview by Alex Xu — System design interview guide
- Cracking the Coding Interview by Gayle McDowell — Classic interview preparation book