Two Pointers
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.
🎯 Two Sum II
Find two numbers in a sorted array that add up to a target.
🌊 Container With Most Water
Find two lines forming the container with the most water.
🔺 3Sum
Find all unique triplets that sum to zero.
✂️ Remove Duplicates
Remove duplicates in-place from a sorted array.
🌧️ Trapping Rain Water
Calculate water trapped between bars after raining.
🔤 Valid Palindrome
Check if a string reads the same forwards and backwards.
[-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.)|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]=100 | right-- |
| left=0 (-4²=16), right=3 (3²=9) | → | result[3]=16 | left++ |
| left=1 (-1²=1), right=3 (3²=9) | → | result[2]=9 | right-- |
| left=1 (-1²=1), right=2 (0²=0) | → | result[1]=1 | left++ |
| left=2=right (0²=0) | → | result[0]=0 | done |
[0, 1, 9, 16, 100] — O(n) time, O(n) space.Sliding Window
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.
🪟 Max Sum Subarray of Size K
Find the contiguous subarray of length k with the largest sum.
🔤 Longest Substring Without Repeating
Find the longest substring with no duplicate characters.
🔍 Minimum Window Substring
Find the smallest substring containing all characters of t.
🔁 Longest Repeating Char Replacement
Longest substring with at most k character replacements.
🔀 Permutation in String
Check if any permutation of s1 is a substring of s2.
📊 Sliding Window Maximum
Return the maximum in every window of size k.
"eceba". Walk through the expand/shrink logic mentally. What's the answer?| 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 left | remove 'e' → "ceb" | still 3! |
| shrink | remove 'c' → "eb" | distinct={e:1,b:1} | len=2 |
| right=4 'a' | 3 distinct! shrink | "ba" | len=2 |
"ece").Binary Search
Eliminate half the search space each step. Classic version works on sorted arrays, but the powerful generalization — "binary search on the answer" — works whenever you have a monotonic predicate.
🔍 Search in Rotated Sorted Array
Find a target in a rotated sorted array in O(log n).
🔎 Find First and Last Position
Find the starting and ending index of a target value.
🔍 Search a 2D Matrix
Search for a target in a row-sorted matrix.
🍌 Koko Eating Bananas
Binary search on the answer — find the minimum eating speed.
🚢 Ship Packages Within D Days
Find minimum ship capacity via binary search on answer.
📊 Median of Two Sorted Arrays
Find the median in O(log(min(m,n))).
√ Sqrt(x)
Find integer square root using binary search.
[100, 200, 150, 80, 300, 50, 120] pages? Frame as binary search on the answer.Predicate:
canFinish(pagesPerDay) = greedily assign chapters to days, start new day when adding a chapter would exceed limit. Check if ≤ 7 days.
| mid=650 | Day1:[100,200,150,80]=530, Day2:[300,50,120]=470 | 2 days ≤ 7 → hi=650 |
| mid=475 | Day1:[100,200,150]=450, Day2:[80,300]=380, Day3:[50,120]=170 | 3 days ≤ 7 → hi=475 |
| mid=387 | Day1:[100,200]=300, Day2:[150,80]=230, Day3:[300], Day4:[50,120]=170 | 4 days → hi=387 |
| mid=343 | similar → works | hi=343 |
| ... | converges to | lo=hi=300 |
Hash Maps & Sets
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.
#️⃣ Two Sum
Find two numbers that add up to target using a hash map.
#️⃣ Group Anagrams
Group strings that are anagrams of each other.
🔗 Longest Consecutive Sequence
Find the longest consecutive sequence in O(n).
Subarray Sum Equals K
Count subarrays with sum equal to k using prefix sums.
🗄️ LRU Cache
Design an O(1) cache with least-recently-used eviction.
🧩 Valid Sudoku
Check if a 9×9 board has valid rows, columns, and boxes.
[100, 4, 200, 1, 3, 2], find the longest consecutive sequence. How does using a set make this O(n)? What's the trick?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: 100 | len=1 |
| 4: 3 in set | → skip (not a start) | |
| 200: 199 not in set | → start! count: 200 | len=1 |
| 1: 0 not in set | → start! count: 1,2,3,4 | len=4 ← max! |
| 3: 2 in set | → skip | |
| 2: 1 in set | → skip |
[1,2,3,4]). Each element is visited at most twice → O(n).Depth-First Search (DFS)
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.
🏝️ Number of Islands
Count connected groups of '1's on a grid.
🔗 Clone Graph
Deep copy a connected undirected graph.
🎓 Course Schedule
Detect if all courses can be finished (cycle detection).
🌳 Path Sum
Find a root-to-leaf path with a target sum.
🔤 Word Search
Find a word in a 2D character grid via DFS.
🌿 Generate Parentheses
Generate all valid combinations of n pairs.
📦 Serialize/Deserialize Tree
Convert a binary tree to string and back.
Algorithm:
1. Scan grid cell by cell
2. When you find a
1: increment island count, then DFS to mark all connected 1s as 03. DFS explores 4 directions (up/down/left/right), base case: out of bounds or cell is
04. 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)
Explore all neighbors at current depth before moving deeper. Uses a queue. Guarantees shortest path in unweighted graphs. Level-order traversal in trees.
🌳 Level Order Traversal
Return binary tree values grouped by level.
🔲 Shortest Path in Binary Matrix
Find shortest path through a grid of 0s and 1s.
🔤 Word Ladder
Find shortest transformation sequence between words.
🍊 Rotting Oranges
Multi-source BFS — how long until all oranges rot?
🔐 Open the Lock
Minimum turns to reach target combination.
♞ Minimum Knight Moves
Minimum chess knight moves to reach (x, y).
"hit" → "cog" via [hot, dot, dog, lot, log, cog]. Why is BFS guaranteed shortest? Would DFS work?| 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) |
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
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.
🪜 Climbing Stairs
How many ways to reach step n (1 or 2 steps at a time)?
🪙 Coin Change
Minimum coins needed to make a target amount.
🔤 Longest Common Subsequence
Find the LCS of two strings using a 2D table.
✏️ Edit Distance
Minimum insert/delete/replace to convert one string to another.
🎒 0/1 Knapsack
Maximum value within a weight capacity.
📈 Longest Increasing Subsequence
Find the longest strictly increasing subsequence.
📝 Word Break
Can a string be segmented into dictionary words?
🏠 House Robber
Maximum robbery without hitting adjacent houses.
🗺️ Unique Paths
Count paths through a grid moving only right or down.
[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[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) |
Backtracking
Systematically explore all candidates by building solutions incrementally, abandoning ("backtracking") as soon as constraints are violated. DFS on the decision tree with pruning.
🔙 Subsets
Generate all possible subsets (power set).
🔀 Permutations
Generate all possible orderings of distinct integers.
🎯 Combination Sum
Find combinations that sum to target (reuse allowed).
♛ N-Queens
Place n queens on a board with no attacks.
🧩 Sudoku Solver
Fill a valid 9×9 Sudoku grid.
🔤 Palindrome Partitioning
Split string into palindromic substrings.
[1, 2, 3]. Trace the decision tree: at each level, you decide include/exclude one element. How many leaf nodes? []
/ \
[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
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.
📏 Non-overlapping Intervals
Minimum removals for no overlaps.
🔗 Merge Intervals
Merge all overlapping intervals.
🦘 Jump Game
Can you reach the last index?
📅 Task Scheduler
Minimum intervals to finish all tasks with cooldown.
⛽ Gas Station
Find the starting station to complete a circular route.
[[0,30],[5,10],[15,20]], find minimum conference rooms needed. How do you track room availability? (Hint: min-heap of end times.)| Meeting [0,30]: | heap empty | → new room | heap=[30], rooms=1 |
| Meeting [5,10]: | heap top=30 > 5 | → can't reuse, new room | heap=[10,30], rooms=2 |
| Meeting [15,20]: | heap top=10 ≤ 15 | → reuse! pop 10, push 20 | heap=[20,30], rooms=2 |
Heap / Priority Queue
Get min/max in O(1), insert/extract in O(log n). Essential for "K-th smallest/largest", merging sorted sources, and streaming medians.
⛰️ Kth Largest Element
Find the k-th largest element in an array.
Merge K Sorted Lists
Merge k sorted linked lists into one.
📊 Find Median from Data Stream
Two-heap approach for streaming median.
🏆 Top K Frequent Elements
Find the k most frequent elements.
🔤 Reorganize String
Rearrange so no two adjacent chars are the same.
| 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 ✓ | |
Monotonic Stack
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).
➡️ Next Greater Element
For each element, find the first larger one to the right.
🌡️ Daily Temperatures
Days until a warmer temperature.
📐 Largest Rectangle in Histogram
Find the largest rectangle under the histogram.
📚 Stock Span Problem
Consecutive days with price ≤ today.
🔢 Remove K Digits
Remove k digits for the smallest possible number.
[73, 74, 75, 71, 69, 72, 76, 73]. For each day, how many days until warmer? Walk through with a decreasing stack.| i=0 (73): | stack empty | push 0 | stack=[0] |
| i=1 (74>73): | pop 0 | ans[0]=1-0=1 | push 1, stack=[1] |
| i=2 (75>74): | pop 1 | ans[1]=2-1=1 | push 2, stack=[2] |
| i=3 (71<75): | push | stack=[2,3] | |
| i=4 (69<71): | push | stack=[2,3,4] | |
| i=5 (72>69,71): | pop 4,3 | ans[4]=1, ans[3]=2 | stack=[2,5] |
| i=6 (76>72,75): | pop 5,2 | ans[5]=1, ans[2]=4 | stack=[6] |
| i=7 (73<76): | push | stack=[6,7] |
[1, 1, 4, 2, 1, 1, 0, 0]. Remaining stack entries get 0 (no warmer day).Union-Find (Disjoint Set)
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.
Connected Components
Count connected components given nodes and edges.
Redundant Connection
Find the extra edge that creates a cycle.
Accounts Merge
Merge accounts sharing at least one email.
[[0,1],[1,2],[2,3],[3,0]], is there a cycle? Walk through union-find.| Init: | parent = [0,1,2,3] (each node is its own set) | ||
| [0,1]: | find(0)=0, find(1)=1 | different → union | parent: 0←1 |
| [1,2]: | find(1)=0, find(2)=2 | different → union | parent: 0←1←2 |
| [2,3]: | find(2)=0, find(3)=3 | different → union | parent: 0←1←2←3 |
| [3,0]: | find(3)=0, find(0)=0 | SAME SET! → CYCLE! | |
Topological Sort
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.
📐 Course Schedule II
Find a valid order to take all courses.
Alien Dictionary
Derive character ordering from a sorted alien wordlist.
Parallel Courses
Minimum semesters with parallel scheduling.
[[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?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! |
[0, 1, 2, 3] or [0, 2, 1, 3] (both valid).Trie (Prefix Tree)
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.
🌳 Implement Trie
Build a trie with insert, search, startsWith.
Word Search II
Find all dictionary words in a 2D grid using trie + DFS.
Add and Search Words
Trie with wildcard '.' support.
['apple', 'app', 'apt', 'bat'] into a Trie. How many nodes? Does search('app') return true? search('ap')?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
Problems involving ranges [start, end]. Almost always: sort by start (or end for scheduling), then process left to right maintaining state.
📏 Insert Interval
Insert a new interval and merge if needed.
Meeting Rooms
Can a person attend all meetings?
Meeting Rooms II
Minimum number of conference rooms needed.
📏 Interval List Intersections
Find all intersections of two interval lists.
[[1,3],[2,6],[8,10],[15,18]]. Merge overlapping. Walk through the comparison logic.| 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]] |
[[1,6],[8,10],[15,18]]. Key: when overlapping, take max(end1, end2) for the merged end.Linked List Techniques
Fast & slow pointers (Floyd's), reversal, dummy head, merge. The toolkit for in-place linked list manipulation without extra space.
🔗 Reverse Linked List
Reverse a linked list iteratively.
🔄 Detect Cycle
Floyd's algorithm for cycle detection.
🔀 Merge Two Sorted Lists
Merge two sorted linked lists into one.
🎯 Remove Nth From End
Remove the n-th node from the end in one pass.
🔃 Reorder List
Interleave first and last elements.
1→2→3→4→5 in groups of 2: result 2→1→4→3→5. What state do you track between groups?| Group 1: [1,2] | reverse → 2→1 | prev_tail=null, connect head to 2 |
| Group 2: [3,4] | reverse → 4→3 | prev_tail=node(1), 1.next=4 |
| Group 3: [5] | size < 2, don't reverse | prev_tail=node(3), 3.next=5 |
2→1→4→3→5Key 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
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.
🔀 Merge Sort
Divide, sort halves, merge. O(n log n) stable.
⚡ Quick Sort
Pivot + partition. In-place, not stable.
🔢 Count Inversions
Count pairs where i < j but a[i] > a[j].
📊 Maximum Subarray
D&C approach: left, right, or crossing midpoint.
[2, 4, 1, 3, 5]. An inversion is (i,j) where i < j but a[i] > a[j]. How does merge sort count these?| Split: [2,4,1] and [3,5] | |||
| Left: [2,4,1] → [2] [4,1] → merge [4,1]: | |||
| pick 1 from right | 1 element left in left half | +1 inversion (4,1) | |
| merged: [1,4]. merge [2] with [1,4]: | |||
| pick 1 from right | 1 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 right | 1 element left (4) | +1 inversion (4,3) | |
Graph: Shortest Path
Dijkstra (BFS + priority queue, non-negative edges) and Bellman-Ford (handles negative edges, detects negative cycles). The foundation of network routing and navigation.
🗺️ Network Delay Time
Time for signal to reach all nodes (Dijkstra).
✈️ Cheapest Flights Within K Stops
Modified Bellman-Ford with stop limit.
🏔️ Path With Minimum Effort
Minimize max height difference on a grid path.
Swim in Rising Water
Minimum time to cross a grid as water rises.
| 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=6 | PQ: [(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. | ||
Bit Manipulation
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.
🔢 Single Number
Find the unique element — every other appears twice.
🔢 Number of 1 Bits
Count set bits (Hamming weight).
🔢 Power of Two
Check if n has exactly one set bit.
🔢 Missing Number
Find the missing number using XOR.
🔢 Reverse Bits
Reverse bits of a 32-bit integer.
[4, 1, 2, 1, 2]. Find the single element using XOR. Walk through step by step.| 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) |
More visualizations are being built. Check back soon!
← Back to memset.dev