The Honest Starting Point
I started my DSA journey terrified of arrays. Genuinely. The idea of writing code that someone would judge, time-limit, and fail felt paralysing. 600+ problems later, I want to share what actually changed — not motivational fluff, but specific mental models and patterns that made me faster.
The Three Phases of DSA Progress
Phase 1: Just Survive (0–100 problems)
The goal here is not efficiency. The goal is to stop being afraid of the problem. I solved easy problems slowly, looked at solutions constantly, and copied patterns without fully understanding them. That's fine. Pattern recognition starts with exposure.
What helped most in this phase: reading solutions after 20-30 minutes of struggling, not after 2 hours. There's a difference between productive struggle and wasteful frustration.
Phase 2: Build Pattern Vocabulary (100–300 problems)
This is where DSA clicked for me. I stopped thinking "what algorithm solves this?" and started thinking "what pattern does this problem fit?"
The core patterns I drilled:
- Two Pointers: Sorted arrays, pairs with a target sum, palindrome checks
- Sliding Window: Subarray/substring problems with a constraint
- Fast/Slow Pointers: Cycle detection, finding middle of linked list
- BFS/DFS: Graphs, trees, grid traversal
- Dynamic Programming: Overlapping subproblems, optimal substructure
- Binary Search: Not just sorted arrays — any monotonic decision function
Phase 3: Combine and Optimize (300–600+)
Hard problems rarely test a single pattern. They're combinations: BFS + priority queue, DP + binary search, graph + union-find. At this phase, the challenge is recognizing which patterns combine and in what order.
The Mental Model That Changed Everything
Every problem falls into one of three categories:
- Search: Find something in a data structure. (BFS, DFS, Binary Search)
- Optimization: Find the best among valid options. (DP, Greedy, Priority Queue)
- Construction: Build something step by step. (Stack, Recursion, Backtracking)
Before writing any code, I now ask: "Is this search, optimization, or construction?" That question alone narrows the algorithm space dramatically.
Solving Dynamic Programming Problems
DP scared me most. The moment I switched from "find the formula" to "define the state clearly first," everything changed.
My DP template:
// Step 1: Define the state
// dp[i] = "the answer for the first i elements"
// Step 2: Write the base case
dp[0] = base_value
// Step 3: Write the recurrence relation
// dp[i] = f(dp[i-1], dp[i-2], ...)
// Step 4: Determine the order of computation
// Example: Coin Change (Classic DP)
function coinChange(coins: number[], amount: number): number {
const dp = new Array(amount + 1).fill(Infinity);
dp[0] = 0;
for (let i = 1; i <= amount; i++) {
for (const coin of coins) {
if (coin <= i) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
}
return dp[amount] === Infinity ? -1 : dp[amount];
}
Graph Problems: The Framework
Every graph problem I encounter now gets the same initial analysis:
- Directed or undirected?
- Weighted or unweighted?
- Is it a tree? (No cycles, n-1 edges)
- What am I finding? (Path, cycle, components, shortest path)
// Universal BFS template
function bfs(start: number, graph: number[][]): number[] {
const visited = new Set();
const queue: number[] = [start];
const result: number[] = [];
visited.add(start);
while (queue.length > 0) {
const node = queue.shift()!;
result.push(node);
for (const neighbor of graph[node]) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
queue.push(neighbor);
}
}
}
return result;
}
What Platforms I Used and Why
- LeetCode: Best problem quality. Use this for FAANG-style interview prep.
- GeeksforGeeks: Best explanations. Great when you need to understand a concept deeply.
- CodeChef: Competitive programming style. Good for speed and contest experience.
The Most Important Advice
Don't memorize solutions. Understand the decision that leads to the solution. The "why" matters more than the "what."
When I review a problem I got wrong, I don't just copy the correct answer. I ask:
- What clue in the problem should have pointed me to this pattern?
- What's the constraint that makes the brute force infeasible?
- How would I recognize this pattern in a different problem?
💡 600+ problems isn't the goal. 600+ problems understood deeply is the goal. Ten well-understood problems beat a hundred memorized ones every time in an actual interview.