DSA Patterns Master Guide: How To Identify Problems, Pick Patterns, and Practice (With LeetCode Sets)
DSA Patterns Master Guide
Most interview problems are variants of a small set of patterns. Your job is not to memorize 500 solutions, but to map a problem to a pattern, recall a small algorithm template, and adapt it. This guide shows you how to identify each pattern, when to use it, the typical steps, common pitfalls, and a focused LeetCode practice set.
How to Use This Guide
- Read the identification cues. Train your eyes to spot keywords and shapes.
- Memorize the small algorithm steps. Build the solution skeleton first.
- Practice 3 to 5 problems per pattern with spaced repetition.
- After solving, write a 5 line retrospective: pattern, key decision, complexity, 1 pitfall, 1 variation.
Two Pointers
Visual:
head <---- array ----> tail l -> ......... <- r fast/slow for cycle detection
Java template:
int l = 0, r = nums.length - 1; while (l < r) { long sum = (long) nums[l] + nums[r]; if (sum == target) { /* use/update */ l++; r--; } else if (sum < target) l++; else r--; }
- Identify it when:
- Array or string, sorted or sortable.
- Need pair, triplet, or partitioning.
- Move pointers inward or with fast-slow positions.
- Core options: head-tail inward, same direction fast-slow, in-place partitioning.
- Steps template:
- Sort if needed.
- Initialize left and right or slow and fast.
- Move based on comparison, update answer, avoid duplicates.
- Pitfalls: off-by-one, duplicate handling, infinite loops when both pointers fail to move.
- Complexity: O(n) or O(n log n) with sort, O(1) extra space.
- LeetCode set: Reverse String 344; Two Sum II 167; Remove Duplicates from Sorted Array 26; Container With Most Water 11; Trapping Rain Water 42.
Sliding Window
Visual:
[l ........ r] grow r; while invalid -> shrink l
Java template (variable window):
int l = 0; Map<Character,Integer> freq = new HashMap<>(); int best = 0; for (int r = 0; r < s.length(); r++) { char c = s.charAt(r); freq.put(c, freq.getOrDefault(c, 0) + 1); while (!isValid(freq)) { char d = s.charAt(l++); freq.put(d, freq.get(d) - 1); if (freq.get(d) == 0) freq.remove(d); } best = Math.max(best, r - l + 1); }
- Identify it when:
- Substring or subarray with length k, or best score within constraints.
- Max, min, first, shortest, or longest subarray meeting a property.
- Options: fixed size, growing-shrinking, frequency maps for distinct or count constraints.
- Steps template:
- Expand right, add element to state.
- While invalid, shrink left, remove from state.
- Track best answer during valid windows.
- Pitfalls: forgetting to shrink, not updating answer at correct time, wrong invariant.
- Complexity: O(n).
- LeetCode set: Maximum Sum Subarray of Size K (educative style); Longest Substring Without Repeating Characters 3; Minimum Size Subarray Sum 209; Longest Repeating Character Replacement 424; Sliding Window Maximum 239.
Prefix Sum
Visual:
P[i] = a[0] + ... + a[i]; sum(l..r) = P[r] - P[l-1]
Java template (subarray sum = k):
Map<Integer,Integer> seen = new HashMap<>(); seen.put(0, 1); int pref = 0, count = 0; for (int x : nums) { pref += x; count += seen.getOrDefault(pref - k, 0); seen.put(pref, seen.getOrDefault(pref, 0) + 1); }
- Identify it when:
- Range sum or count of something in a range.
- Need O(1) queries after O(n) preprocessing or subarray sums with hash map.
- Options: plain prefix sums; prefix counts; prefix modulo for divisible subarrays.
- Steps template:
- Maintain running prefix.
- Use hash map to store first seen prefix or counts.
- Query subarray via prefix[j] - prefix[i-1] or map lookups.
- Pitfalls: off-by-one with index 0; clearing map incorrectly.
- LeetCode set: Running Sum 1480; Subarray Sum Equals K 560; Find Pivot Index 724; Continuous Subarray Sum 523; Range Sum Query 303.
Binary Search
Visual:
lo .... mid .... hi (predicate monotonic)
Java template (leftmost true):
int lo = L, hi = R, ans = -1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (check(mid)) { ans = mid; hi = mid - 1; } else lo = mid + 1; }
- Identify it when:
- Array is sorted or answer is monotonic in a search space.
- You can ask: if I pick mid, should I go left or right.
- Options: index search, boundary search, binary search on answer.
- Steps template:
- low, high; while low <= high.
- mid; check condition C(mid).
- Move low or high; track best boundary.
- Pitfalls: infinite loop when mid calculation or update is wrong; off-by-one on boundaries.
- LeetCode set: Binary Search 704; Search Insert Position 35; Search in Rotated Sorted Array 33; Find Minimum in Rotated Sorted Array 153; Median of Two Sorted Arrays 4.
Intervals and Merge
Visual:
---- ---- ----- -- \___merge___/ push
Java template (merge intervals):
Arrays.sort(iv, (a,b) -> Integer.compare(a[0], b[0])); List<int[]> res = new ArrayList<>(); for (int[] cur : iv) { if (res.isEmpty() || cur[0] > res.get(res.size()-1)[1]) res.add(new int[]{cur[0], cur[1]}); else res.get(res.size()-1)[1] = Math.max(res.get(res.size()-1)[1], cur[1]); }
- Identify it when:
- Merge, insert, or schedule non-overlapping intervals.
- Options: sort by start; sweep line; priority queue by end time.
- Steps template:
- Sort by start.
- If overlap with last, merge; else push.
- For meeting rooms, track end times in min-heap.
- LeetCode set: Merge Intervals 56; Insert Interval 57; Meeting Rooms II 253; Non-overlapping Intervals 435; Employee Free Time 759.
Trees (DFS and BFS)
Visual:
n / \n l r
Java template (DFS):
int dfs(TreeNode node) { if (node == null) return 0; int L = dfs(node.left), R = dfs(node.right); return combine(L, R, node); }
- Identify it when:
- Binary tree traversal, path sums, symmetric or balanced checks.
- Options: pre/in/post-order DFS; BFS level order; recursion vs stack.
- Steps template:
- Choose traversal order.
- Define function(node) -> combine child results.
- Handle base case null.
- LeetCode set: Maximum Depth of Binary Tree 104; Symmetric Tree 101; Binary Tree Level Order Traversal 102; Lowest Common Ancestor 236; Serialize and Deserialize Binary Tree 297.
Graphs
Visual:
Topo: queue of indegree==0 BFS: frontier layers
Java template (Topo Kahn):
Queue<Integer> q = new ArrayDeque<>(); for (int i = 0; i < n; i++) if (indeg[i] == 0) q.add(i); List<Integer> order = new ArrayList<>(); while (!q.isEmpty()) { int u = q.poll(); order.add(u); for (int v : adj[u]) if (--indeg[v] == 0) q.add(v); }
- Identify it when:
- Connectivity, shortest path, topological order, or components.
- Options: BFS, DFS, Dijkstra, Union-Find, Kahn for topo, cycle detection.
- Steps template:
- Build adjacency list.
- Pick traversal based on weights.
- Track visited, parent, or distance.
- LeetCode set: Number of Islands 200; Clone Graph 133; Course Schedule 207; Word Ladder 127; Network Delay Time 743.
Linked List
Visual:
head -> a -> b -> c
Java template (reverse):
ListNode prev = null, cur = head; while (cur != null) { ListNode nxt = cur.next; cur.next = prev; prev = cur; cur = nxt; }
- Identify it when:
- Reversals, merging, cycle detection, reordering.
- Options: fast-slow pointers; dummy head; in-place reverse.
- Steps template:
- Use dummy; split or reverse part.
- Connect carefully with saved next.
- Use fast-slow for cycle and middle.
- LeetCode set: Reverse Linked List 206; Linked List Cycle 141; Merge Two Sorted Lists 21; Add Two Numbers 2; Copy List with Random Pointer 138.
Stack and Monotonic Stack
Visual:
Maintain increasing/decreasing stack of indices
Java template (monotonic):
int n = nums.length; int[] ans = new int[n]; Deque<Integer> st = new ArrayDeque<>(); for (int i = 0; i < n; i++) { while (!st.isEmpty() && breakCond(nums[st.peek()], nums[i])) { int j = st.pop(); ans[j] = i - j; } st.push(i); }
- Identify it when:
- Next greater element, valid parentheses, span or histogram problems.
- Options: plain stack for validation; monotonic increasing or decreasing stacks.
- Steps template:
- For parentheses, push expected closers.
- For monotonic, pop while break condition, compute area or distance.
- Push current with index/value.
- LeetCode set: Valid Parentheses 20; Min Stack 155; Daily Temperatures 739; Next Greater Element II 503; Largest Rectangle in Histogram 84.
Dynamic Programming
Visual:
Table f[i][j] or 1D rolling array
Java template (bottom-up):
for (int i = 0; i <= n; i++) { for (int j = 0; j <= m; j++) { dp[i][j] = bestOfChoices(i,j); } }
- Identify it when:
- Overlapping subproblems, optimal substructure, count ways or max score.
- Options: 1D or 2D DP, knapsack, LIS, partition, edit distance.
- Steps template:
- Define state f(i, j).
- Write recurrence from choices.
- Order of evaluation bottom-up; or memoize top-down.
- LeetCode set: Climbing Stairs 70; House Robber 198; Longest Increasing Subsequence 300; Coin Change 322; Edit Distance 72.
Backtracking
Visual:
choose -> explore -> undo
Java template:
List<List<Integer>> ans = new ArrayList<>(); void dfs(int i) { if (done(i)) { ans.add(new ArrayList<>(path)); return; } for (int c : choices(i)) { if (!feasible(c)) continue; apply(c); path.add(c); dfs(next(i)); path.remove(path.size()-1); undo(c); } }
- Identify it when:
- Search all combinations, permutations, n-queens, subsets with constraints.
- Options: choose or skip; for loops with start index; pruning with feasibility checks.
- Steps template:
- Add current choice.
- Recurse to next position.
- Backtrack by undoing choice.
- LeetCode set: Subsets 78; Permutations 46; Combination Sum 39; N-Queens 51; Word Search 79.
Heap and Priority Queue
Visual:
Maintain size K; max-heap or min-heap by need
Java template (top K):
PriorityQueue<int[]> h = new PriorityQueue<>((a,b)->a[0]-b[0]); for (int[] x : items) { h.offer(x); if (h.size() > K) h.poll(); }
- Identify it when:
- Top K, running median, scheduling by earliest finishing or highest frequency.
- Options: min-heap, max-heap, custom comparator, heap of heaps.
- Steps template:
- Push candidates with priority.
- Pop to maintain size K or pick next job.
- For streaming, rebalance two heaps.
- LeetCode set: Kth Largest Element in an Array 215; Top K Frequent Elements 347; Merge K Sorted Lists 23; Reorganize String 767; Find Median from Data Stream 295.
Greedy
Visual:
sort by key; take if feasible
Java template:
Arrays.sort(items, (a,b) -> key(a) - key(b)); for (var it : items) if (feasible(it)) take(it);
- Identify it when:
- Local choices lead to global optimum for scheduling, intervals, or coin-like problems.
- Options: sort by a ratio, earliest finish, or difference; prove exchange argument.
- Steps template:
- Sort by greedy key.
- Pick if feasible; skip otherwise.
- Maintain running answer.
- LeetCode set: Assign Cookies 455; Jump Game 55; Gas Station 134; Task Scheduler 621; Candy 135.
Bit Manipulation
Visual:
XOR cancels pairs; masks enumerate subsets
Java template:
int ans = 0; for (int x : nums) ans ^= x;
- Identify it when:
- Parity, unique number among duplicates, subsets via bitmasks.
- Options: XOR, bit count, bit DP, masks.
- Steps template:
- Use XOR to cancel pairs.
- Shift and mask to test bits.
- Precompute bit counts if needed.
- LeetCode set: Single Number 136; Number of 1 Bits 191; Counting Bits 338; Sum of Two Integers 371; Maximum Product of Word Lengths 318.
Union-Find (Disjoint Set)
Visual:
parent + rank; path compression
Java template:
int find(int x){ return p[x]==x? x : (p[x]=find(p[x])); } void unite(int a,int b){ int ra=find(a), rb=find(b); if (ra==rb) return; if (rank[ra]<rank[rb]) p[ra]=rb; else if (rank[rb]<rank[ra]) p[rb]=ra; else { p[rb]=ra; rank[ra]++; } }
- Identify it when:
- Grouping connectivity, number of components, cycle detection in undirected graphs.
- Options: union by rank, path compression, union by size.
- Steps template:
- Make set for every node.
- For every edge, union(u, v).
- Count unique parents.
- LeetCode set: Number of Provinces 547; Redundant Connection 684; Accounts Merge 721; Graph Valid Tree 261; Smallest String With Swaps 1202.
Math and Geometry
Visual:
Use identities; cross product for orientation
Java snippet (fast pow):
long pow(long a, long e){ long r=1; while(e>0){ if((e&1)==1) r*=a; a*=a; e>>=1; } return r; }
- Identify it when:
- Pure math function or geometric constraints.
- Options: binary exponentiation, integer sqrt, vector cross product, angle sorting.
- Steps template:
- Reduce using algebraic identity.
- Watch overflow and precision.
- Use geometry primitives.
- LeetCode set: Power of Two 231; Sqrt(x) 69; Happy Number 202; Plus One 66; Rotate Image 48.
Design, LRU, and System-Style Questions
Visual:
HashMap + DoublyLinkedList -> O(1) get/put/evict
Java sketch (LRU core):
class LRU { static class Node{int k,v; Node p,n;} Map<Integer,Node> map = new HashMap<>(); Node h = new Node(), t = new Node(); LRU(){ h.n=t; t.p=h; } void moveFront(Node x){ remove(x); insertAfter(h,x);} void insertAfter(Node a, Node x){ x.n=a.n; x.p=a; a.n.p=x; a.n=x; } void remove(Node x){ x.p.n=x.n; x.n.p=x.p; } }
- Identify it when:
- Caching, rate limiting, LFU/LRU, simple system components.
- Options: hashmap + doubly linked list; counters with TTL; token bucket.
- Steps template:
- Design API surface.
- Pick core data structure pair.
- Define complexity and eviction behavior.
- LeetCode set: Min Stack 155; LRU Cache 146; LFU Cache 460; Design Twitter 355; Serialize and Deserialize Binary Tree 297.
Practice Plan
- Week 1: Two Pointers, Sliding Window, Prefix Sum.
- Week 2: Binary Search, Intervals, Trees.
- Week 3: Graphs, Linked List, Stack.
- Week 4: DP, Backtracking.
- Week 5: Heap, Greedy, Bit Manipulation.
- Week 6: Union-Find, Math, Design.
For each pattern session: solve 3 problems blind, then 1 timed, then explain out loud the choices, invariants, and complexity.
Pattern Decision Cheat Sheet
- Subarray with constraint -> Sliding Window.
- Range sums -> Prefix Sum.
- Sorted or monotone answer -> Binary Search.
- Merge or schedule -> Intervals + Greedy or Heap.
- Paths, connectivity -> Graph + BFS/DFS or Union-Find.
- Build from choices -> DP or Backtracking.
- Top K or stream -> Heap.
- Next greater or validation -> Stack or Monotonic Stack.
Table of Contents
- Two Pointers
- Sliding Window
- Prefix Sum
- Binary Search
- Intervals and Merge
- Trees (DFS and BFS)
- Graphs
- Linked List
- Stack and Monotonic Stack
- Dynamic Programming
- Backtracking
- Heap and Priority Queue
- Greedy
- Bit Manipulation
- Union-Find (Disjoint Set)
- Math and Geometry
- Design, LRU, and System-Style Questions
Related Articles
Incident Playbook for Beginners: Real-World Monitoring and Troubleshooting Stories
A story-driven, plain English incident playbook for new backend & SRE engineers. Find, fix, and prevent outages with empathy and practical steps.
System Design Power-Guide 2025: What To Learn, In What Order, With Real-World Links
Stop bookmarking random threads. This is a tight, no-fluff map of what to study for system design in 2025 - what each topic is, why it matters in interviews and production, and where to go deeper.
Searching & Sorting Master Guide: Visuals, Java Templates, Variants, and LeetCode Sets
A senior-architect style playbook for entry-level engineers: how to identify which search or sort to use, step-by-step templates in Java, key variants, complexity cheats, pitfalls, and curated LeetCode practice.