|
| 1 | +--- |
| 2 | +title: LeetCode Patterns Knowledge Graph (33 Problems) — API Kernels → Patterns → Problems 🎯 |
| 3 | +markmap: |
| 4 | + colorFreezeLevel: 2 |
| 5 | + maxWidth: 300 |
| 6 | +--- |
| 7 | + |
| 8 | +## 🎯 How to use this mind map (fast) |
| 9 | +- **Read top-down**: *API Kernel* → *Pattern* → *Problems* (linked) |
| 10 | +- **Practice loop**: implement template → solve 2–3 problems → refactor into reusable `solve(pattern_state_machine)` mental model |
| 11 | +- **Progress tracking** |
| 12 | + - [ ] Do all **Easy** first |
| 13 | + - [ ] Then **Medium** variants |
| 14 | + - [ ] Finally **Hard** “edge-case amplifiers” |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## 🧠 API Kernels (the “engines”) |
| 19 | +### SubstringSlidingWindow — *1D window state machine* |
| 20 | +- ==Core invariant==: window `[L,R]` stays valid by **expand right** + **contract left** |
| 21 | +- Complexity: typically $O(n)$ time, $O(\Sigma)$ space (alphabet / distinct keys) |
| 22 | + |
| 23 | +<!-- markmap: fold --> |
| 24 | +#### Pattern cheat sheet (from docs) |
| 25 | +| Problem | Invariant | State | Window Size | Goal | |
| 26 | +|---------|-----------|-------|-------------|------| |
| 27 | +| [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py) | All unique | last index map | Variable | Max | |
| 28 | +| [LeetCode 340 - Longest Substring with At Most K Distinct Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0340_longest_substring_with_at_most_k_distinct.py) | ≤K distinct | freq map | Variable | Max | |
| 29 | +| [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) | covers `t` | need/have | Variable | Min | |
| 30 | +| [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py) | exact freq match | freq + matches | Fixed | Exists | |
| 31 | +| [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py) | exact freq match | freq + matches | Fixed | All | |
| 32 | +| [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py) | sum ≥ target | integer sum | Variable | Min | |
| 33 | + |
| 34 | +#### Patterns |
| 35 | +- **sliding_window_unique** *(maximize, “jump left” optimization)* |
| 36 | + - 🎯 Problems |
| 37 | + - [ ] [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py) |
| 38 | + - Key state: `last_seen[char]` → `L = max(L, last_seen[c]+1)` |
| 39 | +- **sliding_window_at_most_k_distinct** *(maximize, shrink while invalid)* |
| 40 | + - 🎯 Problems |
| 41 | + - [ ] [LeetCode 340 - Longest Substring with At Most K Distinct Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0340_longest_substring_with_at_most_k_distinct.py) |
| 42 | + - Key invariant: `len(freq) <= k` |
| 43 | +- **sliding_window_freq_cover** *(cover / exact-match family)* |
| 44 | + - 🎯 Problems |
| 45 | + - [ ] [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) — *minimize while valid* |
| 46 | + - [ ] [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py) — *fixed window, collect indices* |
| 47 | + - [ ] [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py) — *fixed window, boolean* |
| 48 | +- **sliding_window_cost_bounded** *(numeric constraint)* |
| 49 | + - 🎯 Problems |
| 50 | + - [ ] [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py) |
| 51 | + - Typical requirement: positives → monotone contraction works |
| 52 | + |
| 53 | +--- |
| 54 | + |
| 55 | +### TwoPointersTraversal — *pointer choreography on sequences* |
| 56 | +- ==Core invariant==: pointers move deterministically; processed region is “safe” |
| 57 | +- Complexity: often $O(n)$ time, $O(1)$ space (except sorting step) |
| 58 | + |
| 59 | +#### Pattern comparison (from docs) |
| 60 | +| Pattern | Pointer Init | Movement | Termination | Time | Space | Key Use Case | |
| 61 | +|---------|--------------|----------|-------------|------|-------|--------------| |
| 62 | +| Opposite | `0, n-1` | toward center | `L>=R` | $O(n)$ | $O(1)$ | sorted pairs / palindrome / maximize | |
| 63 | +| Same-direction | `write, read` | forward | `read==n` | $O(n)$ | $O(1)$ | in-place modify | |
| 64 | +| Fast–Slow | `slow, fast` | 1× / 2× | meet or null | $O(n)$ | $O(1)$ | cycle / midpoint | |
| 65 | +| Dedup enum | `i` + `L,R` | nested | done | $O(n^2)$ | $O(1)$ | 3Sum/4Sum | |
| 66 | + |
| 67 | +#### Patterns |
| 68 | +- **two_pointer_opposite_maximize** |
| 69 | + - 🎯 Problems |
| 70 | + - [ ] [LeetCode 11 - Container With Most Water](https://github.com/lufftw/neetcode/blob/main/solutions/0011_container_with_most_water.py) |
| 71 | + - Insight: move the pointer at the **shorter** height |
| 72 | +- **two_pointer_three_sum** *(dedup enumeration)* |
| 73 | + - 🎯 Problems |
| 74 | + - [ ] [LeetCode 15 - 3Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0015_3sum.py) |
| 75 | + - [ ] [LeetCode 16 - 3Sum Closest](https://github.com/lufftw/neetcode/blob/main/solutions/0016_3sum_closest.py) |
| 76 | + - Requires: sort first ($O(n\log n)$), then scan with dedup |
| 77 | +- **two_pointer_opposite_palindrome** |
| 78 | + - 🎯 Problems |
| 79 | + - [ ] [LeetCode 125 - Valid Palindrome](https://github.com/lufftw/neetcode/blob/main/solutions/0125_valid_palindrome.py) |
| 80 | + - [ ] [LeetCode 680 - Valid Palindrome II](https://github.com/lufftw/neetcode/blob/main/solutions/0680_valid_palindrome_ii.py) |
| 81 | +- **two_pointer_writer_dedup** |
| 82 | + - 🎯 Problems |
| 83 | + - [ ] [LeetCode 26 - Remove Duplicates from Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0026_remove_duplicates_from_sorted_array.py) |
| 84 | + - [ ] [LeetCode 80 - Remove Duplicates from Sorted Array II](https://github.com/lufftw/neetcode/blob/main/solutions/0080_remove_duplicates_from_sorted_array_ii.py) |
| 85 | +- **two_pointer_writer_remove** |
| 86 | + - 🎯 Problems |
| 87 | + - [ ] [LeetCode 27 - Remove Element](https://github.com/lufftw/neetcode/blob/main/solutions/0027_remove_element.py) |
| 88 | +- **two_pointer_writer_compact** |
| 89 | + - 🎯 Problems |
| 90 | + - [ ] [LeetCode 283 - Move Zeroes](https://github.com/lufftw/neetcode/blob/main/solutions/0283_move_zeroes.py) |
| 91 | + |
| 92 | +--- |
| 93 | + |
| 94 | +### FastSlowPointers — *Floyd + midpoints + implicit sequences* |
| 95 | +- ==Core invariant==: if a cycle exists, `fast` meets `slow` |
| 96 | +- Patterns |
| 97 | + - **fast_slow_cycle_detect** |
| 98 | + - [ ] [LeetCode 141 - Linked List Cycle](https://github.com/lufftw/neetcode/blob/main/solutions/0141_linked_list_cycle.py) |
| 99 | + - **fast_slow_cycle_start** |
| 100 | + - [ ] [LeetCode 142 - Linked List Cycle II](https://github.com/lufftw/neetcode/blob/main/solutions/0142_linked_list_cycle_ii.py) |
| 101 | + - **fast_slow_midpoint** |
| 102 | + - [ ] [LeetCode 876 - Middle of the Linked List](https://github.com/lufftw/neetcode/blob/main/solutions/0876_middle_of_the_linked_list.py) |
| 103 | + - **fast_slow_implicit_cycle** |
| 104 | + - [ ] [LeetCode 202 - Happy Number](https://github.com/lufftw/neetcode/blob/main/solutions/0202_happy_number.py) |
| 105 | + |
| 106 | +--- |
| 107 | + |
| 108 | +### TwoPointerPartition — *in-place partitioning “mini quicksort”* |
| 109 | +- ==Core invariant==: regions are partitioned by property |
| 110 | +- Patterns |
| 111 | + - **dutch_flag_partition** |
| 112 | + - [ ] [LeetCode 75 - Sort Colors](https://github.com/lufftw/neetcode/blob/main/solutions/0075_sort_colors.py) |
| 113 | + - **two_way_partition** |
| 114 | + - [ ] [LeetCode 905 - Sort Array By Parity](https://github.com/lufftw/neetcode/blob/main/solutions/0905_sort_array_by_parity.py) |
| 115 | + - [ ] [LeetCode 922 - Sort Array By Parity II](https://github.com/lufftw/neetcode/blob/main/solutions/0922_sort_array_by_parity_ii.py) |
| 116 | + - **quickselect_partition** *(selection via partition)* |
| 117 | + - [ ] [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py) |
| 118 | + |
| 119 | +--- |
| 120 | + |
| 121 | +### MergeSortedSequences — *merge two sorted sequences* |
| 122 | +- ==Core invariant==: output prefix is fully sorted |
| 123 | +- Patterns |
| 124 | + - **merge_two_sorted_lists** |
| 125 | + - [ ] [LeetCode 21 - Merge Two Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0021_merge_two_sorted_lists.py) |
| 126 | + - **merge_two_sorted_arrays** |
| 127 | + - [ ] [LeetCode 88 - Merge Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0088_merge_sorted_array.py) |
| 128 | + - **merge_sorted_from_ends** |
| 129 | + - [ ] [LeetCode 977 - Squares of a Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0977_squares_of_a_sorted_array.py) |
| 130 | + |
| 131 | +--- |
| 132 | + |
| 133 | +### KWayMerge — *merge K sorted sequences* |
| 134 | +- Two main implementations |
| 135 | + - **merge_k_sorted_heap** → $O(N\log k)$ time, $O(k)$ heap |
| 136 | + - **merge_k_sorted_divide** → $O(N\log k)$ time, smaller constants sometimes |
| 137 | +- 🎯 Problems |
| 138 | + - [ ] [LeetCode 23 - Merge k Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0023_merge_k_sorted_lists.py) |
| 139 | + - Related “hybrid thinking”: [LeetCode 4 - Median of Two Sorted Arrays](https://github.com/lufftw/neetcode/blob/main/solutions/0004_median_of_two_sorted_arrays.py) |
| 140 | + |
| 141 | +--- |
| 142 | + |
| 143 | +### HeapTopK — *keep best K under streaming updates* |
| 144 | +- Patterns |
| 145 | + - **heap_kth_element** |
| 146 | + - [ ] [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py) |
| 147 | + |
| 148 | +--- |
| 149 | + |
| 150 | +### LinkedListInPlaceReversal — *pointer surgery* |
| 151 | +- Pattern |
| 152 | + - **linked_list_k_group_reversal** |
| 153 | + - [ ] [LeetCode 25 - Reverse Nodes in k-Group](https://github.com/lufftw/neetcode/blob/main/solutions/0025_reverse_nodes_in_k_group.py) |
| 154 | +- Also core linked list arithmetic |
| 155 | + - [ ] [LeetCode 2 - Add Two Numbers](https://github.com/lufftw/neetcode/blob/main/solutions/0002_add_two_numbers.py) |
| 156 | + |
| 157 | +--- |
| 158 | + |
| 159 | +### BacktrackingExploration — *search tree with pruning* |
| 160 | +- Pattern |
| 161 | + - **backtracking_n_queens** |
| 162 | + - [ ] [LeetCode 51 - N-Queens](https://github.com/lufftw/neetcode/blob/main/solutions/0051_n_queens.py) |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +### GridBFSMultiSource — *wavefront propagation on grids* |
| 167 | +- Pattern |
| 168 | + - **grid_bfs_propagation** |
| 169 | + - [ ] [LeetCode 994 - Rotting Oranges](https://github.com/lufftw/neetcode/blob/main/solutions/0994_rotting_oranges.py) |
| 170 | +- Implementation invariant: queue holds frontier of current “minute/level” |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +## 🧭 Roadmap slices (what to do next) |
| 175 | +### Sliding Window Mastery 📚 |
| 176 | +- [ ] [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py) |
| 177 | +- [ ] [LeetCode 340 - Longest Substring with At Most K Distinct Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0340_longest_substring_with_at_most_k_distinct.py) |
| 178 | +- [ ] [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py) |
| 179 | +- [ ] [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py) |
| 180 | +- [ ] [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py) |
| 181 | +- [ ] [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) 🔥 |
| 182 | + |
| 183 | +### Two Pointers Mastery ⚡ |
| 184 | +- Opposite pointers |
| 185 | + - [ ] [LeetCode 11 - Container With Most Water](https://github.com/lufftw/neetcode/blob/main/solutions/0011_container_with_most_water.py) |
| 186 | + - [ ] [LeetCode 125 - Valid Palindrome](https://github.com/lufftw/neetcode/blob/main/solutions/0125_valid_palindrome.py) |
| 187 | + - [ ] [LeetCode 680 - Valid Palindrome II](https://github.com/lufftw/neetcode/blob/main/solutions/0680_valid_palindrome_ii.py) |
| 188 | +- Writer pointers (in-place) |
| 189 | + - [ ] [LeetCode 26 - Remove Duplicates from Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0026_remove_duplicates_from_sorted_array.py) |
| 190 | + - [ ] [LeetCode 27 - Remove Element](https://github.com/lufftw/neetcode/blob/main/solutions/0027_remove_element.py) |
| 191 | + - [ ] [LeetCode 283 - Move Zeroes](https://github.com/lufftw/neetcode/blob/main/solutions/0283_move_zeroes.py) |
| 192 | + - [ ] [LeetCode 80 - Remove Duplicates from Sorted Array II](https://github.com/lufftw/neetcode/blob/main/solutions/0080_remove_duplicates_from_sorted_array_ii.py) |
| 193 | +- Fast–slow |
| 194 | + - [ ] [LeetCode 141 - Linked List Cycle](https://github.com/lufftw/neetcode/blob/main/solutions/0141_linked_list_cycle.py) |
| 195 | + - [ ] [LeetCode 142 - Linked List Cycle II](https://github.com/lufftw/neetcode/blob/main/solutions/0142_linked_list_cycle_ii.py) |
| 196 | + - [ ] [LeetCode 876 - Middle of the Linked List](https://github.com/lufftw/neetcode/blob/main/solutions/0876_middle_of_the_linked_list.py) |
| 197 | + - [ ] [LeetCode 202 - Happy Number](https://github.com/lufftw/neetcode/blob/main/solutions/0202_happy_number.py) |
| 198 | + |
| 199 | +--- |
| 200 | + |
| 201 | +## 🧩 “Same problem, different lens” (transfer learning) |
| 202 | +- **Selection**: [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py) |
| 203 | + - Option A: `quickselect_partition` (expected $O(n)$) |
| 204 | + - Option B: `heap_kth_element` ($O(n\log k)$, streaming-friendly) |
| 205 | +- **Merging**: |
| 206 | + - 2-way: [LeetCode 21 - Merge Two Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0021_merge_two_sorted_lists.py), [LeetCode 88 - Merge Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0088_merge_sorted_array.py) |
| 207 | + - K-way: [LeetCode 23 - Merge k Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0023_merge_k_sorted_lists.py) |
| 208 | + - “boundary + merge thinking”: [LeetCode 4 - Median of Two Sorted Arrays](https://github.com/lufftw/neetcode/blob/main/solutions/0004_median_of_two_sorted_arrays.py) |
| 209 | + |
| 210 | +--- |
| 211 | + |
| 212 | +## 🧱 Minimal reusable templates (mental API) |
| 213 | +```python |
| 214 | +# Sliding Window (variable, maximize) |
| 215 | +def max_window(seq): |
| 216 | + state = {} |
| 217 | + L = 0 |
| 218 | + ans = 0 |
| 219 | + for R, x in enumerate(seq): |
| 220 | + add(state, x) |
| 221 | + while invalid(state): |
| 222 | + remove(state, seq[L]); L += 1 |
| 223 | + ans = max(ans, R - L + 1) |
| 224 | + return ans |
| 225 | + |
| 226 | +# Two pointers (opposite) |
| 227 | +def opposite(arr): |
| 228 | + L, R = 0, len(arr) - 1 |
| 229 | + while L < R: |
| 230 | + if should_move_left(arr, L, R): |
| 231 | + L += 1 |
| 232 | + else: |
| 233 | + R -= 1 |
| 234 | +``` |
| 235 | + |
| 236 | +--- |
0 commit comments