The Only DSA Guide You’ll Ever Need | Dev Blog
📘 Interview Prep · DSA

The Only DSA Guide
You’ll Actually Need

40 problems. 11 topics. Every trick, pattern, and mental model—explained the way no textbook does.

🗓 2026 Edition 15 min read 🎯 Interview Ready
Scroll

You Don’t Need to Solve 500 LeetCode Problems

Here’s the uncomfortable truth most people won’t tell you: DSA interviews test patterns, not memory. You don’t need to have solved every problem—you need to recognize which mental model applies in the first 60 seconds of reading a question.

This guide is built around that idea. For each topic, we give you the core trick—the one insight that unlocks 80% of the problems in that category. Master the pattern, and the individual problems solve themselves.

⚡ The 80/20 Rule of DSA
Two Pointers, HashMap, Sliding Window, DFS/BFS, and Dynamic Programming together cover the vast majority of what gets asked in real interviews. If you understand these five deeply, you’re ahead of most candidates.

Arrays — The Foundation of Everything

Arrays are involved in nearly every interview problem, either directly or as supporting structure. The reason they’re so dominant: they support random access, work great with two pointers, and serve as the backbone for prefix sums and hash-based lookups.

🧠 Master Mental Model
Three tools solve 90% of array problems: Two Pointers for pairs/windows, Prefix Sum for range queries, and HashMap for O(1) lookups. When stuck, ask yourself which of these three applies.

The Problems & Their Tricks

ARRAY · 01
Largest & Smallest Element
Single pass. Track two variables: min and max. Update both in the same iteration.
Don’t sort! Sorting is O(n log n). A single scan is O(n).
ARRAY · 02
Reverse an Array
Two Pointers: left starts at 0, right starts at n-1. Swap, then move both inward.
No extra space needed. while (left < right) is the loop condition—not ≤.
ARRAY · 03
Find Duplicates
HashMap: store each value as you iterate. If it already exists—duplicate found.
If O(1) space required, use XOR: XOR of all elements and all indices leaves only the duplicate.
ARRAY · 04
Max Subarray (Kadane’s)
curSum = max(num, curSum + num). If current sum goes negative, reset and start fresh.
Track maxSum separately. curSum is your running total; maxSum is the answer so far.
ARRAY · 05
Two Sum
One-pass HashMap: for each number, check if target - num already exists before inserting.
Check complement before inserting current element—prevents pairing a number with itself.
ARRAY · 06
Missing Number
Expected sum = n*(n+1)/2. Subtract actual sum. The difference is the missing number.
XOR alternative: XOR all indices (0 to n) and all values. Missing number remains.

Linked Lists — All About Pointers

Linked list problems look intimidating until you internalize one truth: almost every question is solved with the slow + fast pointer technique. Two pointers moving at different speeds can detect cycles, find midpoints, and compute distances from the end—without knowing the list’s length.

🧠 Master Mental Model
Slow pointer moves 1 step. Fast pointer moves 2 steps. When fast hits null → slow is at the middle. When slow == fast → there’s a cycle. That’s it. That’s most of linked lists.

Reversing a Linked List — The Code Template

let prev = null, curr = head; // While there’s a node to process… while (curr !== null) { let next = curr.next; // 1. Save next curr.next = prev; // 2. Reverse the pointer prev = curr; // 3. Move prev forward curr = next; // 4. Move curr forward } return prev; // New head

The pattern is always: save next → reverse → advance. Draw it out on paper once, and it’ll never confuse you again.

Floyd’s Cycle Detection — The Full Insight

Most people know Phase 1: use slow/fast pointers to detect a cycle. But interviews often ask you to also find where the cycle starts. Here’s the trick: once slow and fast meet inside the cycle, reset slow to head. Now move both one step at a time. Where they meet again is the cycle entry point—provable with simple math.

Stack — Order, History, and “Nearest”

The stack is the data structure of recent memory. Whenever a problem asks about the nearest greater/smaller element, matching brackets, or tracking something “since the last time X happened”—reach for a stack.

🧠 Master Mental Model
Stack = “I’ve seen this but haven’t resolved it yet.” Push when uncertain. Pop when the condition is finally met. The monotonic stack takes this further: keep the stack always increasing or always decreasing to find nearest neighbors fast.

Monotonic Stack for Next Greater Element

const result = new Array(n).fill(-1); const stack = []; // Stores indices for (let i = 0; i < n; i++) { // While current element is greater than stack’s top while (stack.length && arr[stack.at(-1)] < arr[i]) { result[stack.pop()] = arr[i]; // Found next greater } stack.push(i); }

Key insight: store indices, not values. That way you can directly write answers into the result array.

Queue & Sliding Window

The queue’s superpower is the monotonic deque—a double-ended queue that maintains a max or min across a moving window. The sliding window maximum problem is the canonical example, and it appears in many disguised forms.

🧠 Master Mental Model
Monotonic Deque: Remove from the front when the index is outside the window. Remove from the back when the new element is better (larger for max). Front always holds the answer.

Recursion & Backtracking — The Template

Backtracking is just recursion with an undo step. Every backtracking problem follows the same three-part template— memorize this and you’ll never stare blankly at a “generate all X” problem again.

  • 1Make a choice — add an element to your current path or state
  • 2Recurse — explore all options from this new state
  • 3Undo the choice — remove the element and try the next option
🧠 Master Mental Model
Always define three things before coding: (1) What is the base case? (2) What changes between recursive calls? (3) What are you building up? If you can answer these, the code practically writes itself.

Trees — The Most Asked Data Structure

Binary trees appear in more interview questions than almost any other structure. The good news: almost every tree problem is a variation of one insight—apply some logic to the root, then recurse on both children.

Two traversal strategies dominate: DFS (recursion, good for height/paths/LCA) and BFS (queue-based, good for level-order and shortest distance).

🧠 Master Mental Model
Ask yourself: “Do I need to process nodes level by level or go deep first?” Level by level → BFS with a queue. Deep first → DFS with recursion. When in doubt, DFS is usually simpler to write.

Balanced Tree Check — The Sentinel Trick

function checkHeight(node) { if (!node) return 0; const left = checkHeight(node.left); const right = checkHeight(node.right); // -1 = “something below is unbalanced” if (left === –1 || right === –1) return1; if (Math.abs(left – right) > 1) return1; return 1 + Math.max(left, right); }

The -1 sentinel propagates upward automatically. Once any subtree is unbalanced, -1 flows up and kills the whole check immediately—no extra boolean needed.

Level Order — The Snapshot Trick

When doing BFS level-by-level, take a snapshot of queue.size() at the start of each level. Process exactly that many nodes, then increment the level counter. This cleanly separates levels without needing a null separator.

Binary Search Trees — Exploit the Property

A BST’s defining property—left < root < right—is both its strength and the thing many people forget to fully exploit. Every time you visit a node, you can eliminate an entire half of the tree based on whether the target is smaller or larger.

🧠 Master Mental Model
Inorder traversal of a BST gives a sorted array. This one fact solves Kth Smallest, validates a BST, finds closest values, and more. Memorize this and it’ll save you in many problems.

Hashing — Frequency & Grouping

A HashMap gives O(1) average lookup—but its real power is in how you define the key. Sorted string as key → groups anagrams. Character frequency array as key → groups permutations. The trick isn’t using a HashMap; it’s choosing what to hash.

🧠 Master Mental Model
Ask: “What property should two elements share to belong in the same group?” That property is your key. If two strings are anagrams, their sorted form is identical. If two arrays have the same frequency distribution, their int[26] array is identical.

Graphs — Traversal Fundamentals

Graph problems look complex until you realize most of them reduce to: visit every reachable node exactly once. The two tools for this are BFS (shortest path, level order) and DFS (connected components, cycle detection, topological sort).

🧠 Most Common Mistake
Marking nodes as visited when dequeued (instead of when enqueued) is the #1 bug in BFS. If you wait until dequeue, the same node can enter the queue multiple times, causing incorrect results and infinite loops. Always mark visited at the moment of enqueuing.

Topological Sort (Kahn’s Algorithm)

Used for ordering tasks with dependencies (think: build systems, course prerequisites). Compute in-degrees for all nodes. Enqueue all nodes with in-degree 0. Process: dequeue a node, reduce neighbor in-degrees, enqueue any that reach 0. If you don’t process all nodes, there’s a cycle.

Dynamic Programming — The Most Tested Topic

DP is the biggest gap in most people’s preparation. It’s also the most tested topic at mid and senior levels. The secret: DP is just recursion with a cache. If you can write the recursive solution, you can write the DP solution.

🧠 The 4-Step DP Framework
1. Define clearly what dp[i] means in plain English.
2. Write the recurrence relation (how dp[i] relates to smaller subproblems).
3. Identify base cases (what dp[0] or dp[1] equals).
4. Choose top-down (memoization) or bottom-up (tabulation).

DP Problems & Their Core Recurrences

Problem Recurrence Space Trick
Fibonacci dp[i] = dp[i-1] + dp[i-2] Only keep 2 variables → O(1)
0/1 Knapsack dp[w] = max(dp[w], dp[w-wt]+val) Inner loop goes right→left
LCS match: 1+dp[i-1][j-1], else max(skip) Use 2 rows instead of full table
LIS dp[i] = max(dp[j]+1) where arr[j]<arr[i] Patience sorting → O(n log n)
Coin Change dp[a] = min(dp[a-coin]+1) Init with amount+1 as “infinity”
⚡ The Knapsack Inner Loop Trick
In 1D (space-optimized) 0/1 Knapsack, the inner loop must go backwards (right to left). Why? Going left to right means you’d use the same item twice in one pass—accidentally converting it to an unbounded knapsack.

Heap / Priority Queue — Top-K Problems

The heap is the right tool whenever you need the K best elements from a stream or large dataset. The counterintuitive key insight is this: to find the K largest elements, use a min-heap of size K.

🧠 Why Min-Heap for K Largest?
You want to keep the K largest. The min-heap’s top is the smallest of those K. If a new element is larger than the top, it deserves to be in the top K—so pop the top and push the new element. After processing all elements, the heap holds exactly the K largest. The top is your answer for Kth largest.

6 Algorithms Every Developer Must Know

Beyond data structure operations, these six algorithms appear repeatedly—sometimes as the main problem, often as a subtask inside a larger one. Know them cold.

AlgorithmWhen to UseComplexityKey Gotcha
Binary Search Sorted array, search for value or boundary O(log n) Use left + (right-left)/2 to avoid integer overflow
Merge Sort Need stable sort; sorting linked lists O(n log n) Always O(n log n)—no worst case. Requires O(n) extra space.
Quick Sort General purpose in-place sorting O(n log n) avg Sorted input → O(n²). Use random pivot or median-of-three.
BFS Shortest path (unweighted), level order O(V+E) Mark visited on enqueue, not dequeue
DFS Cycles, paths, connected components, topo sort O(V+E) Cycle detection needs in-stack tracking, not just visited[]
Dijkstra Shortest path in weighted graph (no neg. weights) O((V+E) log V) init dist[start]=0, all others=∞. Always process min-dist node first.

See a Problem → Know the Pattern Instantly

This is the table to study the night before an interview. Read the left column, recall the right column. If you can do that fluently, you’re ready.

If the problem involves…Reach for…
Find a pair/triplet with sum XTwo Pointers or HashMap
Max/min over a contiguous subarraySliding Window
Missing or duplicate in 1..NXOR or Sum Formula
Sorted array + searchingBinary Search
All subsets / combinations / permutationsBacktracking
Nearest greater or smaller elementMonotonic Stack
Shortest path in unweighted graph/gridBFS
Overlapping subproblems, optimal substructureDynamic Programming
Top K elements from stream or arrayHeap / Priority Queue
Cycle detection (list or graph)Slow+Fast Pointer / DFS w/ colors
Tree height, depth, or root-to-leaf pathDFS (Recursion)
Minimum depth / level-by-level processingBFS with Queue
Character frequency or grouping stringsHashMap
Task ordering with dependenciesTopological Sort (Kahn’s)
Weighted shortest path (no negatives)Dijkstra’s Algorithm
✅ Recommended Revision Order

Arrays → Linked Lists → Stack/Queue → Trees → Graphs → DP → Heap

Solve 2–3 problems per topic. Focus on recognizing patterns, not memorizing solutions.

The Honest Bottom Line

DSA isn’t about grinding 500 problems. It’s about building a clear mental map of which tool solves which type of problem. The developers who do well in interviews aren’t the ones who’ve seen every problem before—they’re the ones who can decompose an unfamiliar problem into a familiar pattern within 60 seconds.

Study the patterns above until they’re automatic. Implement each one once from scratch. Review this guide the week before any interview. That’s the formula—no magic required.

Good luck. You’ve got this. 🚀

Cover all 11 topics · 40 problems · Every trick that matters