Algorithm Visualizations

Interactive, step-by-step visualizations of classic coding interview patterns. Watch algorithms run, tweak the inputs, build intuition — not just memorization.

⚠️ These visualizations are AI-generated and may contain inaccuracies. Always verify against the original problem statements on LeetCode.
19
Patterns
119
Problems
100%
Interactive
👆

Two Pointers

Easy Very High Frequency

Use two pointers (indices) to traverse a data structure — from both ends toward the middle, or both from the start at different speeds. Reduces nested loops from O(n²) to O(n). The sorted array's best friend.

When to use → Input is sorted · Looking for pairs/triplets · Compare from opposite ends · "in-place" on sorted data · "two elements", "pair", "subarray boundaries"
⏱ 5-Min Challenge
Given a sorted array [-4, -1, 0, 3, 10], square each element and return a sorted array of squares. Which variant of two pointers works here and why? (Hint: negatives become large when squared.)
Use pointers at both ends. After squaring, the largest values are at the edges (large negatives → large positives). Compare |arr[left]| vs |arr[right]|, place the larger square at the end of the result, move that pointer inward.
left=0 (-4²=16), right=4 (10²=100)result[4]=100right--
left=0 (-4²=16), right=3 (3²=9)result[3]=16left++
left=1 (-1²=1), right=3 (3²=9)result[2]=9right--
left=1 (-1²=1), right=2 (0²=0)result[1]=1left++
left=2=right (0²=0)result[0]=0done
Answer: [0, 1, 9, 16, 100] — O(n) time, O(n) space.
🪟

Sliding Window

Easy-Medium Very High Frequency

Maintain a contiguous subarray/substring "window" that expands or contracts as you iterate. Track window state incrementally — add the new element, remove the old. Fixed-size or variable-size.

When to use → "Contiguous subarray" or "substring" · "Maximum/minimum length" · "At most K distinct" · Fixed window size · O(n) needed where brute force is O(n²)
⏱ 5-Min Challenge
Find the longest substring with at most 2 distinct characters in "eceba". Walk through the expand/shrink logic mentally. What's the answer?
Variable-size sliding window with a hash map tracking character counts.
right=0 'e'window="e"distinct={e:1}len=1
right=1 'c'window="ec"distinct={e:1,c:1}len=2
right=2 'e'window="ece"distinct={e:2,c:1}len=3 ← max!
right=3 'b'3 distinct! shrink leftremove 'e' → "ceb"still 3!
shrinkremove 'c' → "eb"distinct={e:1,b:1}len=2
right=4 'a'3 distinct! shrink"ba"len=2
Answer: 3 (substring "ece").
#️⃣

Hash Maps & Sets

Easy Very High Frequency

Trade space for time — O(1) average lookup. The go-to for "have I seen this?" and "how many times?" Store key→value pairs or unique values to eliminate nested loops.

When to use → "Find if element exists" · Frequency counting · Need O(1) lookup · "Group by" · Prefix sum problems · Deduplication
⏱ 5-Min Challenge
Given [100, 4, 200, 1, 3, 2], find the longest consecutive sequence. How does using a set make this O(n)? What's the trick?
Trick: only start counting from sequence beginnings. Put all numbers in a set. For each number, check if num-1 exists — if it does, skip it (it's not a start). Only count forward from true starts.
100: 99 not in set→ start! count: 100len=1
4: 3 in set→ skip (not a start)
200: 199 not in set→ start! count: 200len=1
1: 0 not in set→ start! count: 1,2,3,4len=4 ← max!
3: 2 in set→ skip
2: 1 in set→ skip
Answer: 4 (sequence [1,2,3,4]). Each element is visited at most twice → O(n).
🌲

Depth-First Search (DFS)

Medium Very High Frequency

Explore as deep as possible along each branch before backtracking. Uses a stack (explicit or recursion). For trees, graphs, and grids — cycle detection, connected components, flood fill.

When to use → Tree/graph traversal · "Find all paths" · Grid problems · Explore all possibilities · Recursive structure · "Is there a cycle?"
⏱ 5-Min Challenge
On a 4×4 grid, count the number of islands (connected groups of 1s). When you find a 1, what do you do to avoid counting the same island twice?
Mark visited cells. When DFS finds a 1, it changes it to 0 (or marks as visited) before recursing into neighbors. This "sinks" the island so it won't be counted again.

Algorithm:
1. Scan grid cell by cell
2. When you find a 1: increment island count, then DFS to mark all connected 1s as 0
3. DFS explores 4 directions (up/down/left/right), base case: out of bounds or cell is 0
4. After DFS returns, the entire island is "sunk" — continue scanning

Key insight: mutating the input grid avoids needing a separate visited set. Time: O(rows × cols), Space: O(rows × cols) worst case for recursion stack.
🌊

Breadth-First Search (BFS)

Medium Very High Frequency

Explore all neighbors at current depth before moving deeper. Uses a queue. Guarantees shortest path in unweighted graphs. Level-order traversal in trees.

When to use → "Shortest path" or "minimum steps" · Level-by-level processing · "Minimum transformations" · Multi-source spread (fire, infection)
⏱ 5-Min Challenge
Word Ladder: transform "hit""cog" via [hot, dot, dog, lot, log, cog]. Why is BFS guaranteed shortest? Would DFS work?
BFS explores all transformations at distance k before distance k+1. So the first time we reach "cog", it's guaranteed to be the shortest path.
Level 0:hit
Level 1:hot(hit→hot: change i→o)
Level 2:dot, lot(hot→dot, hot→lot)
Level 3:dog, log(dot→dog, lot→log)
Level 4:cog(dog→cog or log→cog)
Answer: 5 words in chain (hit → hot → dot → dog → cog).

DFS would find a path but not necessarily the shortest. It might go hit→hot→lot→log→cog (also 5) or take a longer route. BFS guarantees minimum.
📊

Dynamic Programming

Medium-Hard Very High Frequency

Break problems into overlapping subproblems with optimal substructure. Solve each once, store results. Top-down (memoization) or bottom-up (tabulation). The key is defining the STATE and TRANSITION.

When to use → "Count the number of ways" · "Find the min/max cost" · "Can you partition?" · Overlapping subproblems · Recursive solution is correct but TLE
⏱ 5-Min Challenge
Coin Change: coins = [1, 3, 4], amount = 6. Define dp[i] = minimum coins for amount i. Fill the table from 0 to 6. What's dp[6]?
dp[i] = min(dp[i - coin] + 1) for each coin that fits.
dp[0] = 0(base case)
dp[1] = dp[1-1]+1 = 1(one coin: 1)
dp[2] = dp[2-1]+1 = 2(two 1s)
dp[3] = min(dp[2]+1, dp[0]+1) = 1(one coin: 3)
dp[4] = min(dp[3]+1, dp[1]+1, dp[0]+1) = 1(one coin: 4)
dp[5] = min(dp[4]+1, dp[2]+1) = 2(4+1)
dp[6] = min(dp[5]+1, dp[3]+1, dp[2]+1) = 2(3+3)
Answer: dp[6] = 2 (coins: 3 + 3).
🔙

Backtracking

Medium High Frequency

Systematically explore all candidates by building solutions incrementally, abandoning ("backtracking") as soon as constraints are violated. DFS on the decision tree with pruning.

When to use → "Generate all" / "find all valid" · Constraint satisfaction · Decision tree structure · Small n (≤ 15-20)
⏱ 5-Min Challenge
Generate all subsets of [1, 2, 3]. Trace the decision tree: at each level, you decide include/exclude one element. How many leaf nodes?
Decision tree with 3 levels (one per element), 2 branches each (include/exclude).
                    []
           /                  \
         [1]                  []
        /    \              /    \
     [1,2]   [1]         [2]    []
     / \     / \         / \    / \
 [1,2,3][1,2][1,3][1] [2,3][2][3] []
8 leaf nodes = 2³ subsets:
[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]
🎯

Greedy Algorithms

Medium High Frequency

Make the locally optimal choice at each step. Works when a locally optimal choice is part of some globally optimal solution. Often: sort first, then one pass.

When to use → Interval problems · "Minimum number of" · Sorting + one-pass · Natural priority (biggest first, earliest deadline) · Can prove local best never hurts
⏱ 5-Min Challenge
Meeting Rooms II: given intervals [[0,30],[5,10],[15,20]], find minimum conference rooms needed. How do you track room availability? (Hint: min-heap of end times.)
Sort by start time. Min-heap tracks when each room becomes free.
Meeting [0,30]:heap empty→ new roomheap=[30], rooms=1
Meeting [5,10]:heap top=30 > 5→ can't reuse, new roomheap=[10,30], rooms=2
Meeting [15,20]:heap top=10 ≤ 15→ reuse! pop 10, push 20heap=[20,30], rooms=2
Answer: 2 rooms. The min-heap lets us check in O(log n) if any room is free (its end time ≤ current start).
⛰️

Heap / Priority Queue

Medium High Frequency

Get min/max in O(1), insert/extract in O(log n). Essential for "K-th smallest/largest", merging sorted sources, and streaming medians.

When to use → "K-th largest/smallest" · "Top K" · "Median" in a stream · Merging sorted sources · Scheduling with priorities
⏱ 5-Min Challenge
Find the median from a data stream: addNum(1), addNum(2), findMedian() → 1.5, addNum(3), findMedian() → 2. Trace the two-heap approach.
Max-heap (left half) stores smaller numbers, min-heap (right half) stores larger. Median = top of right heap (odd count) or average of both tops (even).
add(1):maxH=[], minH=[]→ maxH=[1], minH=[]rebalance → maxH=[], minH=[1]
add(2):2 ≥ minH.top(1)→ minH=[1,2]rebalance → maxH=[1], minH=[2]
median:even count(1+2)/2 = 1.5 ✓
add(3):3 ≥ minH.top(2)→ minH=[2,3]rebalance → maxH=[1,2], minH=[3]
median:odd count (3)maxH.top = 2 ✓
Rule: Keep sizes balanced (differ by at most 1). Median is always accessible from the heap tops in O(1).
📚

Monotonic Stack

Medium Medium-High Frequency

A stack maintaining monotonic order. When a new element would violate order, pop until invariant is restored. Answers "next/previous greater/smaller" in O(n).

When to use → "Next greater/smaller element" · Histogram problems · "Remove elements to optimize" · Need left/right boundary for each element
⏱ 5-Min Challenge
Temperatures = [73, 74, 75, 71, 69, 72, 76, 73]. For each day, how many days until warmer? Walk through with a decreasing stack.
Decreasing stack of indices. When temp[i] > stack top, pop and record difference.
i=0 (73):stack emptypush 0stack=[0]
i=1 (74>73):pop 0ans[0]=1-0=1push 1, stack=[1]
i=2 (75>74):pop 1ans[1]=2-1=1push 2, stack=[2]
i=3 (71<75):pushstack=[2,3]
i=4 (69<71):pushstack=[2,3,4]
i=5 (72>69,71):pop 4,3ans[4]=1, ans[3]=2stack=[2,5]
i=6 (76>72,75):pop 5,2ans[5]=1, ans[2]=4stack=[6]
i=7 (73<76):pushstack=[6,7]
Answer: [1, 1, 4, 2, 1, 1, 0, 0]. Remaining stack entries get 0 (no warmer day).
🔗

Union-Find (Disjoint Set)

Medium Medium Frequency

Track which elements belong to the same group. find(x) and union(x,y) in nearly O(1) amortized with path compression + union by rank. Perfect for dynamic connectivity.

When to use → "Connected components" · "Are X and Y connected?" · "Group/merge" dynamically · Cycle detection (undirected) · Kruskal's MST
⏱ 5-Min Challenge
Given edges [[0,1],[1,2],[2,3],[3,0]], is there a cycle? Walk through union-find.
Process edges one by one. Cycle = both endpoints already in the same set.
Init:parent = [0,1,2,3] (each node is its own set)
[0,1]:find(0)=0, find(1)=1different → unionparent: 0←1
[1,2]:find(1)=0, find(2)=2different → unionparent: 0←1←2
[2,3]:find(2)=0, find(3)=3different → unionparent: 0←1←2←3
[3,0]:find(3)=0, find(0)=0SAME SET! → CYCLE!
Answer: Yes, cycle detected on edge [3,0]. Both endpoints already connected.
📐

Topological Sort

Medium Medium Frequency

Linear ordering of DAG vertices where for every edge u→v, u comes before v. Kahn's BFS (in-degree tracking) or DFS reverse postorder. Detects cycles in directed graphs.

When to use → Dependencies / prerequisites · "Order of operations" · "Valid ordering?" · DAG processing
⏱ 5-Min Challenge
Courses: [[1,0],[2,0],[3,1],[3,2]]. Draw the DAG and find a valid order using Kahn's: which nodes start with in-degree 0?
Build graph, track in-degrees, process zero-in-degree nodes.
  0 → 1 → 3
  |         ↑
  +→ 2 →-+
In-degrees:0:0, 1:1, 2:1, 3:2
Queue start:[0] (only zero-in-degree node)
Process 0:decrement 1→0, 2→0. Queue: [1,2]
Process 1:decrement 3→1. Queue: [2]
Process 2:decrement 3→0. Queue: [3]
Process 3:Queue empty. Done!
Valid order: [0, 1, 2, 3] or [0, 2, 1, 3] (both valid).
🌳

Trie (Prefix Tree)

Medium Medium Frequency

A tree where each node represents a character and paths from root represent prefixes. O(L) insert/search/prefix-check regardless of dictionary size. Powers autocomplete and spell checkers.

When to use → "Prefix matching" / "starts with" · Multiple string searches · Autocomplete · Word games · "Find all words that..."
⏱ 5-Min Challenge
Insert ['apple', 'app', 'apt', 'bat'] into a Trie. How many nodes? Does search('app') return true? search('ap')?
Nodes = root + unique prefix characters.
root
├─ a
│  └─ p
│     ├─ p (end:app) ✓
│     │  └─ l
│     │     └─ e (end:apple) ✓
│     └─ t (end:apt) ✓
└─ b
   └─ a
      └─ t (end:bat) ✓
Nodes created: 10 (root + a,p,p,l,e,t,b,a,t). Shared prefixes save space!

search("app")true ✓ (node 'p' at depth 3 has isEnd=true)
search("ap")false ✗ (node 'p' at depth 2 has isEnd=false)
startsWith("ap")true ✓ (the prefix path exists)
📏

Interval Problems

Medium Medium-High Frequency

Problems involving ranges [start, end]. Almost always: sort by start (or end for scheduling), then process left to right maintaining state.

When to use → List of [start, end] pairs · "Merge overlapping" · "Find conflicts" · Scheduling / booking · "Minimum to cover/remove"
⏱ 5-Min Challenge
Intervals = [[1,3],[2,6],[8,10],[15,18]]. Merge overlapping. Walk through the comparison logic.
Sort by start (already sorted). Compare current end with next start.
Start with [1,3]merged = [[1,3]]
Next [2,6]:2 ≤ 3 (overlap!)extend → [[1,6]]
Next [8,10]:8 > 6 (no overlap)new interval → [[1,6],[8,10]]
Next [15,18]:15 > 10 (no overlap)new → [[1,6],[8,10],[15,18]]
Answer: [[1,6],[8,10],[15,18]]. Key: when overlapping, take max(end1, end2) for the merged end.
⛓️

Linked List Techniques

Easy-Medium Medium Frequency

Fast & slow pointers (Floyd's), reversal, dummy head, merge. The toolkit for in-place linked list manipulation without extra space.

When to use → Explicit linked list · "Detect cycle" → Floyd's · "Find middle" → fast/slow · "Reverse" → prev/curr/next · "Merge" → dummy head
⏱ 5-Min Challenge
Reverse a linked list 1→2→3→4→5 in groups of 2: result 2→1→4→3→5. What state do you track between groups?
Track: previous group's tail, current group's start, and a counter.
Group 1: [1,2]reverse → 2→1prev_tail=null, connect head to 2
Group 2: [3,4]reverse → 4→3prev_tail=node(1), 1.next=4
Group 3: [5]size < 2, don't reverseprev_tail=node(3), 3.next=5
Result: 2→1→4→3→5

Key state between groups: (1) tail of the previously reversed group (to link it to the new head), (2) the node before the current group (to reconnect), (3) count of processed nodes to know when a group is complete.
✂️

Divide and Conquer

Medium-Hard Medium Frequency

Split into independent subproblems, solve recursively, combine. Unlike DP — subproblems don't overlap. Classic: T(n) = aT(n/b) + O(n^d) analyzed by Master Theorem.

When to use → Problem splits into independent halves · Sorting-related · "Count pairs" (modified merge sort) · Geometric problems · Target O(n log n) with merge step
⏱ 5-Min Challenge
Count inversions in [2, 4, 1, 3, 5]. An inversion is (i,j) where i < j but a[i] > a[j]. How does merge sort count these?
During the merge step: when picking from the right half, ALL remaining left elements are inversions.
Split: [2,4,1] and [3,5]
Left: [2,4,1] → [2] [4,1] → merge [4,1]:
pick 1 from right1 element left in left half+1 inversion (4,1)
merged: [1,4]. merge [2] with [1,4]:
pick 1 from right1 element in left+1 inversion (2,1)
merged: [1,2,4]
Right: [3,5] already sorted, 0 inversions
Final merge: [1,2,4] with [3,5]:
pick 1,2,3—no inversions from picking left elements
pick 3 from right1 element left (4)+1 inversion (4,3)
Answer: 3 inversions — (2,1), (4,1), (4,3).
🗺️

Graph: Shortest Path

Medium-Hard Medium Frequency

Dijkstra (BFS + priority queue, non-negative edges) and Bellman-Ford (handles negative edges, detects negative cycles). The foundation of network routing and navigation.

When to use → "Shortest path" in weighted graph · "Minimum cost to reach" · Non-negative → Dijkstra · Negative edges → Bellman-Ford · "Within K steps"
⏱ 5-Min Challenge
Graph: A→B(1), A→C(4), B→C(2), B→D(5), C→D(1). Shortest path A to D? Trace Dijkstra.
Priority queue (min-heap), process closest unvisited node.
Init:dist = {A:0, B:∞, C:∞, D:∞}PQ: [(0,A)]
Process A (0):B: 0+1=1 < ∞C: 0+4=4 < ∞PQ: [(1,B),(4,C)]
Process B (1):C: 1+2=3 < 4 ✓D: 1+5=6PQ: [(3,C),(4,C),(6,D)]
Process C (3):D: 3+1=4 < 6 ✓PQ: [(4,C),(4,D),(6,D)]
Process D (4):Done! Target reached.
Answer: 4 via path A → B → C → D (1+2+1).
🔢

Bit Manipulation

Easy-Medium Medium Frequency

Bitwise operations (AND, OR, XOR, NOT, shift) to solve problems in O(1) space. Key: x^x=0, x^0=x, x&(x-1) drops lowest set bit, x&(-x) isolates lowest set bit.

When to use → "Single/unique element" · "Power of two" · "Count/flip bits" · Subsets with small n · O(1) space + pairs/cancellation
⏱ 5-Min Challenge
Array = [4, 1, 2, 1, 2]. Find the single element using XOR. Walk through step by step.
XOR all elements. Pairs cancel (x^x=0), leaving the unique one.
Start:result = 0
0 ^ 4 =4(0000 ^ 0100 = 0100)
4 ^ 1 =5(0100 ^ 0001 = 0101)
5 ^ 2 =7(0101 ^ 0010 = 0111)
7 ^ 1 =6(0111 ^ 0001 = 0110)
6 ^ 2 =4(0110 ^ 0010 = 0100)
Answer: 4. The two 1s cancelled, the two 2s cancelled, leaving 4. O(n) time, O(1) space.

More visualizations are being built. Check back soon!

← Back to memset.dev