01 — Data Structures, Algorithms & Coding Interviews
Priority: HIGHEST — This is the make-or-break round in most interviews. Target: Solve LeetCode Medium problems confidently in 20-30 minutes.
Table of Contents
- Mindset & Strategy
- Big-O Complexity Cheat Sheet
- Core Data Structures
- The 15 Essential Coding Patterns
- Pattern-to-Problem Mapping
- The NeetCode 150 Roadmap
- Problem-Solving Framework
- Python-Specific Tips for Coding Interviews
- Practice Schedule
- Resources
Mindset & Strategy
You don’t need to solve 500 problems. You need to:
- Recognize which pattern a problem uses
- Know the template for that pattern
- Adapt the template to the specific problem
- Write clean, bug-free code under time pressure
In the interview:
- Spend 5 min understanding the problem. Ask clarifying questions.
- Spend 5 min planning your approach. State the pattern you’re using.
- Spend 15-20 min coding. Talk through your decisions.
- Spend 5 min testing with examples and edge cases.
- State time and space complexity before the interviewer asks.
Big-O Complexity Cheat Sheet
Time Complexity (sorted best → worst)
| Notation | Name | Example |
|---|---|---|
| O(1) | Constant | Hash table lookup, array index access |
| O(log n) | Logarithmic | Binary search, balanced BST operations |
| O(n) | Linear | Single loop through array, linear search |
| O(n log n) | Linearithmic | Merge sort, heap sort, efficient sorting |
| O(n²) | Quadratic | Nested loops, bubble sort, insertion sort |
| O(2ⁿ) | Exponential | Recursive Fibonacci, power set |
| O(n!) | Factorial | Permutations, traveling salesman brute force |
Space Complexity Quick Rules
- Recursive call stack: O(depth of recursion)
- Hash map/set: O(number of unique elements stored)
- Sorting in-place: O(1) extra; merge sort: O(n) extra
- BFS queue: O(width of tree/graph level)
- DFS stack: O(height of tree/depth of graph)
Core Data Structures
1. Arrays & Strings
What to know:
- Indexing, slicing, iteration
- In-place operations (two pointers, swapping)
- Subarray/substring problems
- Sorting-based solutions
Python specifics:
- Lists are dynamic arrays: append O(1) amortized, insert O(n)
- Strings are immutable: concatenation creates new string
- Use list(s) to manipulate characters, then ''.join()
Key problems:
- Two Sum (hash map approach)
- Best Time to Buy and Sell Stock
- Container With Most Water
- Longest Substring Without Repeating Characters
- Group Anagrams
2. Hash Maps & Hash Sets
What to know:
- O(1) average lookup, insert, delete
- Collision resolution (chaining vs open addressing)
- When to use: frequency counting, deduplication, lookup table
- Counter, defaultdict in Python
Python specifics:
- dict preserves insertion order (Python 3.7+)
- collections.Counter for frequency counting
- collections.defaultdict to avoid KeyError
- set for O(1) membership testing
Key problems:
- Two Sum
- Valid Anagram
- Top K Frequent Elements
- Longest Consecutive Sequence
3. Linked Lists
What to know:
- Singly vs Doubly linked
- In-place operations (no random access)
- Pointer manipulation (next, prev)
- Dummy head node trick
Common patterns:
- Fast/slow pointer (cycle detection, middle of list)
- Reversing a linked list (iterating 3 pointers)
- Merge two sorted lists
Key problems:
- Reverse Linked List
- Detect Cycle (Floyd’s algorithm)
- Merge Two Sorted Lists
- Remove Nth Node From End
- LRU Cache (doubly linked list + hash map)
4. Stacks & Queues
Stack (LIFO):
- Push/Pop O(1)
- Use for: matching brackets, monotonic stack, DFS, undo operations
- Python: list (append/pop) or collections.deque
Queue (FIFO):
- Enqueue/Dequeue O(1)
- Use for: BFS, level-order traversal, scheduling
- Python: collections.deque (appendleft/pop or append/popleft)
Monotonic Stack:
- Maintains elements in sorted order
- Use for: next greater element, largest rectangle in histogram
Key problems:
- Valid Parentheses
- Min Stack
- Daily Temperatures (monotonic stack)
- Implement Queue using Stacks
5. Trees
Binary Tree:
- Traversals: inorder, preorder, postorder (recursive + iterative)
- Level-order traversal (BFS with queue)
- Height, depth, diameter
Binary Search Tree (BST):
- Search, insert, delete: O(h) where h = height
- Inorder traversal gives sorted order
- Validate BST: pass min/max bounds
Trie (Prefix Tree):
- For string prefix problems
- Insert/Search: O(word length)
Key problems:
- Maximum Depth of Binary Tree
- Invert Binary Tree
- Lowest Common Ancestor
- Validate BST
- Binary Tree Level Order Traversal
- Serialize and Deserialize Binary Tree
- Implement Trie
6. Heaps (Priority Queues)
What to know:
- Min-heap: smallest element at top
- Max-heap: largest element at top (negate values in Python)
- Insert: O(log n), Extract min/max: O(log n)
- Build heap: O(n)
- Use for: top K elements, merge K sorted lists, median finding
Python specifics:
- heapq module (min-heap only)
- For max-heap: push -val, pop and negate
- heapq.nlargest(k, iterable) and heapq.nsmallest(k, iterable)
Key problems:
- Kth Largest Element in Array
- Top K Frequent Elements
- Find Median from Data Stream (two heaps)
- Merge K Sorted Lists
7. Graphs
Representations:
- Adjacency list: dict[node] = [neighbors] (most common in interviews)
- Adjacency matrix: 2D array (less common, dense graphs)
- Edge list: [(u, v, weight)]
Traversals:
- BFS: level-by-level, shortest path in unweighted graph
- DFS: explores deep first, good for path finding, cycle detection
Key algorithms:
- Topological sort: DAG ordering (Kahn's BFS or DFS-based)
- Dijkstra's: shortest path with positive weights
- Union-Find: connected components, cycle detection in undirected
- Bellman-Ford: shortest path with negative weights (less common)
Key problems:
- Number of Islands (BFS/DFS on grid)
- Clone Graph
- Course Schedule (topological sort)
- Pacific Atlantic Water Flow
- Graph Valid Tree
- Word Ladder (BFS)
8. Dynamic Programming
What to know:
- Identify overlapping subproblems + optimal substructure
- Top-down (memoization) vs Bottom-up (tabulation)
- State definition: what variables define a subproblem?
- Transition: how does a state relate to smaller states?
- Base cases: what are the smallest subproblems?
Common DP categories:
- 1D: climbing stairs, house robber, coin change
- 2D: longest common subsequence, edit distance, unique paths
- Knapsack: 0/1 knapsack, unbounded knapsack
- String matching: regex, wildcard matching
- Interval: matrix chain multiplication, burst balloons
Key problems:
- Climbing Stairs
- House Robber
- Coin Change
- Longest Increasing Subsequence
- Longest Common Subsequence
- Word Break
- 0/1 Knapsack
- Edit Distance
The 15 Essential Coding Patterns
Pattern 1: Two Pointers
When to use:
- Sorted array/list problems
- Finding pairs with a target sum
- Removing duplicates in-place
- Comparing elements from both ends
Template:
left, right = 0, len(arr) - 1
while left < right:
# compare arr[left] and arr[right]
# move left++ or right-- based on condition
Must-solve: Two Sum II, 3Sum, Container With Most Water, Trapping Rain Water
Pattern 2: Sliding Window
When to use:
- Contiguous subarray/substring problems
- "Maximum/minimum subarray of size K"
- "Longest substring with condition"
Template (variable-size window):
left = 0
for right in range(len(arr)):
# expand: add arr[right] to window state
while window_condition_violated:
# shrink: remove arr[left] from window state
left += 1
# update answer
Must-solve: Max Sum Subarray of Size K, Longest Substring Without Repeating Characters, Minimum Window Substring, Permutation in String
Pattern 3: Fast & Slow Pointers
When to use:
- Cycle detection in linked list or array
- Finding middle of linked list
- Finding start of cycle
Template:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast: # cycle detected
break
Must-solve: Linked List Cycle, Happy Number, Find the Duplicate Number, Middle of Linked List
Pattern 4: Merge Intervals
When to use:
- Overlapping intervals
- Merging, inserting, or scheduling intervals
Template:
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for current in intervals[1:]:
if current[0] <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], current[1])
else:
merged.append(current)
Must-solve: Merge Intervals, Insert Interval, Non-overlapping Intervals, Meeting Rooms I & II
Pattern 5: Binary Search
When to use:
- Sorted array
- "Find target" or "find boundary"
- Search space reduction problems (search on answer)
Template:
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
Advanced — Binary search on answer:
left, right = min_possible, max_possible
while left < right:
mid = (left + right) // 2
if condition(mid):
right = mid
else:
left = mid + 1
Must-solve: Binary Search, Search in Rotated Sorted Array, Find Minimum in Rotated Sorted Array, Koko Eating Bananas, Median of Two Sorted Arrays
Pattern 6: BFS (Breadth-First Search)
When to use:
- Shortest path in unweighted graph
- Level-order traversal
- Exploring neighbors level by level
- Grid/matrix traversal
Template:
from collections import deque
queue = deque([start])
visited = {start}
while queue:
node = queue.popleft()
for neighbor in get_neighbors(node):
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
Must-solve: Number of Islands, Binary Tree Level Order Traversal, Word Ladder, Rotting Oranges, Walls and Gates
Pattern 7: DFS (Depth-First Search)
When to use:
- Path finding
- Cycle detection
- Tree traversals
- Connected components
- Exhaustive search
Template (recursive):
def dfs(node, visited):
visited.add(node)
for neighbor in get_neighbors(node):
if neighbor not in visited:
dfs(neighbor, visited)
Template (iterative with stack):
stack = [start]
visited = set()
while stack:
node = stack.pop()
if node in visited:
continue
visited.add(node)
for neighbor in get_neighbors(node):
stack.append(neighbor)
Must-solve: Max Area of Island, Clone Graph, Pacific Atlantic Water Flow, Course Schedule, Number of Connected Components
Pattern 8: Backtracking
When to use:
- Generate all combinations/permutations/subsets
- Constraint satisfaction (Sudoku, N-Queens)
- Path finding with constraints
Template:
def backtrack(candidates, path, result):
if is_solution(path):
result.append(path[:])
return
for candidate in candidates:
if is_valid(candidate, path):
path.append(candidate)
backtrack(next_candidates, path, result)
path.pop() # undo choice
Must-solve: Subsets, Permutations, Combination Sum, Word Search, N-Queens, Letter Combinations of Phone Number
Pattern 9: Topological Sort
When to use:
- Ordering tasks with dependencies
- Detecting cycles in directed graphs
- Course scheduling
Template (Kahn's BFS):
from collections import deque
in_degree = {node: 0 for node in graph}
for node in graph:
for neighbor in graph[node]:
in_degree[neighbor] += 1
queue = deque([n for n in in_degree if in_degree[n] == 0])
order = []
while queue:
node = queue.popleft()
order.append(node)
for neighbor in graph[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
# If len(order) != len(graph), there's a cycle
Must-solve: Course Schedule, Course Schedule II, Alien Dictionary, Task Scheduler
Pattern 10: Union-Find (Disjoint Set Union)
When to use:
- Connected components
- Cycle detection in undirected graphs
- Grouping/clustering
Template:
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # path compression
return self.parent[x]
def union(self, x, y):
px, py = self.find(x), self.find(y)
if px == py:
return False
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
return True
Must-solve: Number of Connected Components, Redundant Connection, Accounts Merge, Graph Valid Tree
Pattern 11: Monotonic Stack
When to use:
- Next greater/smaller element
- Largest rectangle in histogram
- Stock span problems
Template (next greater element):
stack = [] # stores indices
result = [-1] * len(arr)
for i in range(len(arr)):
while stack and arr[i] > arr[stack[-1]]:
result[stack.pop()] = arr[i]
stack.append(i)
Must-solve: Daily Temperatures, Next Greater Element, Largest Rectangle in Histogram, Trapping Rain Water
Pattern 12: Top-K Elements (Heap)
When to use:
- "Find K largest/smallest/most frequent"
- Running median
- Merging K sorted things
Template:
import heapq
# Top K largest
heap = []
for val in stream:
heapq.heappush(heap, val)
if len(heap) > k:
heapq.heappop(heap)
# heap now contains k largest elements
Must-solve: Kth Largest Element, Top K Frequent Elements, Find Median from Data Stream, Merge K Sorted Lists
Pattern 13: Dynamic Programming
When to use:
- "Count ways to..." / "Minimum/maximum of..."
- Overlapping subproblems
- Optimal substructure
Approach:
1. Define state: dp[i] = ...
2. Find transition: dp[i] = f(dp[i-1], dp[i-2], ...)
3. Set base cases: dp[0] = ..., dp[1] = ...
4. Determine iteration order
5. Optimize space if possible (often only need last 1-2 rows/values)
Must-solve: Coin Change, House Robber, LIS, LCS, Word Break, 0/1 Knapsack, Edit Distance, Decode Ways
Pattern 14: Bit Manipulation
When to use:
- Single number problems (XOR)
- Counting bits
- Power of 2 checks
- Subsets generation
Key operations:
x & (x - 1) # removes lowest set bit
x & (-x) # isolates lowest set bit
x ^ x = 0 # XOR with self = 0
x ^ 0 = x # XOR with 0 = x
Must-solve: Single Number, Number of 1 Bits, Counting Bits, Reverse Bits, Missing Number
Pattern 15: Greedy
When to use:
- Local optimal choice leads to global optimal
- Scheduling, interval problems
- When DP is overkill
Key insight:
Prove greedy works by showing local optimal → global optimal
(or use exchange argument)
Must-solve: Jump Game, Gas Station, Task Scheduler, Partition Labels
Pattern-to-Problem Mapping
Use this to quickly identify which pattern to apply:
| If the problem says… | Consider… |
|---|---|
| ”Sorted array” | Two Pointers, Binary Search |
| ”Subarray/substring of size K” | Sliding Window |
| ”Linked list cycle” | Fast & Slow Pointers |
| ”Overlapping intervals” | Merge Intervals |
| ”Find position/boundary” | Binary Search |
| ”Shortest path (unweighted)“ | BFS |
| ”Path exists” / “connected” | DFS, Union-Find |
| ”All combinations/permutations” | Backtracking |
| ”Task ordering/dependencies” | Topological Sort |
| ”Connected components” | Union-Find, DFS |
| ”Next greater/smaller” | Monotonic Stack |
| ”Top K / Kth largest” | Heap |
| ”Count ways / min-max cost” | Dynamic Programming |
| ”Single/missing number” | Bit Manipulation |
| ”Optimal scheduling” | Greedy |
| ”Matrix traversal” | BFS/DFS |
| ”Tree” | DFS (recursive), BFS (level-order) |
| “Trie/prefix” | Trie data structure |
| ”Stream of data” | Heap, Running statistics |
The NeetCode 150 Roadmap
Follow this order. Solve at least the starred (★) problems.
Arrays & Hashing (9 problems)
- ★ Two Sum
- ★ Valid Anagram
- ★ Group Anagrams
- ★ Top K Frequent Elements
- ★ Encode and Decode Strings
- ★ Product of Array Except Self
- ★ Longest Consecutive Sequence
- Contains Duplicate
- Valid Sudoku
Two Pointers (5 problems)
- ★ Valid Palindrome
- ★ Two Sum II
- ★ 3Sum
- ★ Container With Most Water
- Trapping Rain Water
Sliding Window (6 problems)
- ★ Best Time to Buy and Sell Stock
- ★ Longest Substring Without Repeating Characters
- ★ Longest Repeating Character Replacement
- ★ Minimum Window Substring
- Permutation in String
- Sliding Window Maximum
Stack (7 problems)
- ★ Valid Parentheses
- ★ Min Stack
- ★ Evaluate Reverse Polish Notation
- ★ Daily Temperatures
- Generate Parentheses
- Car Fleet
- Largest Rectangle in Histogram
Binary Search (7 problems)
- ★ Binary Search
- ★ Search a 2D Matrix
- ★ Koko Eating Bananas
- ★ Search in Rotated Sorted Array
- ★ Find Minimum in Rotated Sorted Array
- Time Based Key Value Store
- Median of Two Sorted Arrays
Linked List (11 problems)
- ★ Reverse Linked List
- ★ Merge Two Sorted Lists
- ★ Linked List Cycle
- ★ Remove Nth Node From End
- ★ Reorder List
- ★ LRU Cache
- Add Two Numbers
- Copy List with Random Pointer
- Find the Duplicate Number
- Merge K Sorted Lists
- Reverse Nodes in K-Group
Trees (15 problems)
- ★ Invert Binary Tree
- ★ Maximum Depth of Binary Tree
- ★ Same Tree
- ★ Subtree of Another Tree
- ★ Lowest Common Ancestor of BST
- ★ Binary Tree Level Order Traversal
- ★ Validate BST
- ★ Kth Smallest Element in BST
- ★ Binary Tree from Preorder & Inorder
- Diameter of Binary Tree
- Balanced Binary Tree
- Binary Tree Right Side View
- Count Good Nodes in Binary Tree
- Serialize and Deserialize Binary Tree
- Binary Tree Maximum Path Sum
Tries (3 problems)
- ★ Implement Trie
- ★ Design Add and Search Words
- Word Search II
Heap / Priority Queue (7 problems)
- ★ Kth Largest Element in a Stream
- ★ Last Stone Weight
- ★ K Closest Points to Origin
- ★ Task Scheduler
- ★ Find Median from Data Stream
- Design Twitter
- Kth Largest Element in an Array
Backtracking (9 problems)
- ★ Subsets
- ★ Combination Sum
- ★ Permutations
- ★ Word Search
- ★ Letter Combinations of Phone Number
- Subsets II
- Combination Sum II
- Palindrome Partitioning
- N-Queens
Graphs (13 problems)
- ★ Number of Islands
- ★ Clone Graph
- ★ Pacific Atlantic Water Flow
- ★ Course Schedule
- ★ Number of Connected Components
- ★ Graph Valid Tree
- ★ Word Ladder
- Max Area of Island
- Surrounded Regions
- Rotting Oranges
- Walls and Gates
- Redundant Connection
- Alien Dictionary
Dynamic Programming (12 problems)
- ★ Climbing Stairs
- ★ House Robber
- ★ House Robber II
- ★ Longest Increasing Subsequence
- ★ Coin Change
- ★ Word Break
- ★ Longest Common Subsequence
- ★ Unique Paths
- Min Cost Climbing Stairs
- Partition Equal Subset Sum
- Decode Ways
- Target Sum
Intervals (5 problems)
- ★ Insert Interval
- ★ Merge Intervals
- ★ Non-overlapping Intervals
- ★ Meeting Rooms
- Meeting Rooms II
Greedy (8 problems)
- ★ Maximum Subarray
- ★ Jump Game
- ★ Jump Game II
- ★ Gas Station
- ★ Hand of Straights
- Partition Labels
- Valid Parenthesis String
- Merge Triplets to Form Target
Math & Geometry (8 problems)
- ★ Rotate Image
- ★ Spiral Matrix
- ★ Set Matrix Zeroes
- ★ Happy Number
- ★ Plus One
- Pow(x, n)
- Multiply Strings
- Detect Squares
Bit Manipulation (7 problems)
- ★ Single Number
- ★ Number of 1 Bits
- ★ Counting Bits
- ★ Reverse Bits
- ★ Missing Number
- Sum of Two Integers
- Reverse Integer
Problem-Solving Framework
Use this in every interview:
1. UNDERSTAND (2-3 min)
- Restate the problem in your own words
- Ask: What are the inputs? Outputs? Constraints?
- Ask: What about edge cases? Empty input? Single element? Negative numbers?
- Ask: Can I modify the input? Is it sorted?
2. PLAN (3-5 min)
- Identify the pattern (use the mapping table above)
- State your approach: "I'm going to use a sliding window because..."
- Walk through your approach with a small example
- State expected time/space complexity
3. CODE (15-20 min)
- Write clean, readable code
- Use meaningful variable names
- Handle edge cases first (early returns)
- Talk while you code — narrate your decisions
4. TEST (3-5 min)
- Trace through your code with the given example
- Test edge cases: empty input, single element, all same elements
- Test boundary conditions
- Fix any bugs found
5. OPTIMIZE (if time)
- Can you reduce time complexity?
- Can you reduce space complexity?
- Are there Python-specific optimizations?
Python-Specific Tips for Coding Interviews
Essential Python for Interviews
# --- Collections ---
from collections import defaultdict, Counter, deque, OrderedDict
from heapq import heappush, heappop, heapify, nlargest, nsmallest
from itertools import combinations, permutations, product, accumulate
from functools import lru_cache
from bisect import bisect_left, bisect_right, insort
from math import inf, ceil, floor, gcd, log2
from typing import List, Optional, Tuple, Dict, Set
# --- Frequency counting ---
freq = Counter("hello") # {'l': 2, 'h': 1, 'e': 1, 'o': 1}
freq.most_common(2) # [('l', 2), ('h', 1)]
# --- Default dict ---
graph = defaultdict(list)
graph['a'].append('b') # no KeyError
# --- Deque (O(1) both ends) ---
q = deque([1, 2, 3])
q.appendleft(0) # [0, 1, 2, 3]
q.popleft() # 0
q.append(4) # [1, 2, 3, 4]
# --- Heap ---
heap = [3, 1, 2]
heapify(heap) # [1, 3, 2]
heappush(heap, 0) # [0, 1, 2, 3]
smallest = heappop(heap) # 0
# --- Binary search ---
sorted_arr = [1, 3, 5, 7, 9]
bisect_left(sorted_arr, 5) # 2 (index where 5 is / would be inserted)
bisect_right(sorted_arr, 5) # 3
# --- Memoization ---
@lru_cache(maxsize=None)
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
# --- Sorting ---
arr.sort(key=lambda x: x[1]) # sort by 2nd element
arr.sort(key=lambda x: (-x[1], x[0])) # sort by 2nd desc, then 1st asc
# --- String manipulation ---
s = "hello world"
s.split() # ['hello', 'world']
'_'.join(['a','b']) # 'a_b'
s[::-1] # reverse string
ord('a') # 97
chr(97) # 'a'
# --- List comprehension ---
squares = [x*x for x in range(10)]
flat = [item for sublist in matrix for item in sublist]
filtered = [x for x in arr if x > 0]
# --- Infinity ---
float('inf') # positive infinity
float('-inf') # negative infinity
# --- Tuple unpacking ---
for i, (key, val) in enumerate(pairs):
pass
Common Gotchas
# WRONG: Mutable default argument
def add(item, lst=[]): # lst is shared across calls!
lst.append(item)
return lst
# RIGHT:
def add(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
# WRONG: Shallow copy of nested list
grid = [[0] * 3] * 3 # all 3 rows are the SAME list!
grid[0][0] = 1 # changes ALL rows!
# RIGHT:
grid = [[0] * 3 for _ in range(3)]
# WRONG: Modifying list while iterating
for item in lst:
if condition:
lst.remove(item) # skips elements!
# RIGHT:
lst = [item for item in lst if not condition]
Practice Schedule
Week 1: Foundations (Arrays, Strings, Hash Maps)
- Day 1-2: Two Sum, Valid Anagram, Group Anagrams, Contains Duplicate
- Day 3-4: Best Time to Buy/Sell Stock, Product Except Self, Longest Consecutive
- Day 5-6: Two Pointers pattern (Valid Palindrome, 3Sum, Container With Water)
- Day 7: Review + revisit unsolved problems
Week 2: Core Patterns (Sliding Window, Binary Search, Stacks)
- Day 1-2: Sliding Window problems (Longest Substring, Min Window Substring)
- Day 3-4: Binary Search problems (Rotated Array, Koko Eating Bananas)
- Day 5-6: Stack problems (Valid Parentheses, Daily Temperatures, Min Stack)
- Day 7: Review + timed practice (set 25 min timer per problem)
Week 3: Trees & Graphs
- Day 1-2: Tree traversals, Max Depth, Invert Tree, Same Tree
- Day 3-4: BST problems, LCA, Validate BST, Kth Smallest
- Day 5-6: Graph BFS/DFS (Number of Islands, Clone Graph, Course Schedule)
- Day 7: Review + mock coding interview
Week 4: Advanced Patterns
- Day 1-2: Dynamic Programming basics (Climbing Stairs, House Robber, Coin Change)
- Day 3-4: More DP (LIS, LCS, Word Break, Edit Distance)
- Day 5-6: Backtracking (Subsets, Permutations, Combination Sum, Word Search)
- Day 7: Heap problems (Top K, Median Finder, Merge K Sorted)
Week 5-6: Integration & Timed Practice
- 2 problems per day, 25 minutes each, timed
- Mix of all patterns
- Focus on weak areas
- Weekly mock interview with a peer
Resources
Primary
- NeetCode 150: https://neetcode.io/practice — Video explanations for every problem
- LeetCode Patterns: https://seanprashad.com/leetcode-patterns/ — Grouped by pattern
- Grind 75: https://www.techinterviewhandbook.org/grind75 — Customizable plan
Video Explanations
- NeetCode YouTube: https://www.youtube.com/@NeetCode — Best problem walkthroughs
- Back To Back SWE: https://www.youtube.com/@BackToBackSWE — Deep conceptual explanations
- Abdul Bari: https://www.youtube.com/@abdul_bari — Algorithm fundamentals
Books
- Cracking the Coding Interview by Gayle Laakmann McDowell — classic
- Elements of Programming Interviews in Python — Python-specific
Practice Platforms
- LeetCode: https://leetcode.com — the standard
- HackerRank: https://www.hackerrank.com — good for warmup
- CodeSignal: https://codesignal.com — some companies use this
My Notes
Use this space to track your progress, write down patterns you keep forgetting, and note problems that tripped you up.
Problems I struggled with:
-
Patterns I need to review:
-
Key insights:
-
Next: 02-system-design.md