1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > NeetCode Agent Evolved Mindmap (ZH-TW) - NeetCode Mind Maps</ title >
7+ < style >
8+ * { margin : 0 ; padding : 0 ; box-sizing : border-box; }
9+ html , body { height : 100% ; }
10+ .markmap { width : 100% ; height : 100% ; }
11+ .markmap > svg { width : 100% ; height : 100% ; }
12+ # topbar {
13+ position : fixed; top : 0 ; left : 0 ; right : 0 ; z-index : 100 ;
14+ background : # fff ; border-bottom : 1px solid # e5e7eb ;
15+ padding : 8px 16px ; display : flex; gap : 8px ;
16+ font-family : -apple-system, BlinkMacSystemFont, 'Segoe UI' , sans-serif;
17+ font-size : 13px ;
18+ }
19+ # topbar button {
20+ padding : 4px 12px ; border : 1px solid # d1d5db ;
21+ border-radius : 4px ; background : # fff ; cursor : pointer;
22+ }
23+ # topbar button : hover { background : # f3f4f6 ; }
24+ .markmap { margin-top : 40px ; height : calc (100% - 40px ); }
25+ </ style >
26+ < script src ="https://cdn.jsdelivr.net/npm/d3@7 "> </ script >
27+ < script src ="https://cdn.jsdelivr.net/npm/markmap-view "> </ script >
28+ < script src ="https://cdn.jsdelivr.net/npm/markmap-lib "> </ script >
29+ < script src ="https://cdn.jsdelivr.net/npm/markmap-toolbar "> </ script >
30+ < script >
31+ function fitView ( ) {
32+ var svg = document . querySelector ( '.markmap > svg' ) ;
33+ if ( svg && svg . mm ) svg . mm . fit ( ) ;
34+ }
35+ function expandAll ( ) {
36+ var svg = document . querySelector ( '.markmap > svg' ) ;
37+ if ( svg && svg . mm ) {
38+ var root = svg . mm . state . data ;
39+ ( function expand ( n ) {
40+ n . payload = Object . assign ( { } , n . payload , { fold : 0 } ) ;
41+ if ( n . children ) n . children . forEach ( expand ) ;
42+ } ) ( root ) ;
43+ svg . mm . setData ( root ) ; svg . mm . fit ( ) ;
44+ }
45+ }
46+ function collapseAll ( ) {
47+ var svg = document . querySelector ( '.markmap > svg' ) ;
48+ if ( svg && svg . mm ) {
49+ var root = svg . mm . state . data ;
50+ root . children && root . children . forEach ( function collapse ( n ) {
51+ if ( n . children && n . children . length ) {
52+ n . payload = Object . assign ( { } , n . payload , { fold : 1 } ) ;
53+ n . children . forEach ( collapse ) ;
54+ }
55+ } ) ;
56+ svg . mm . setData ( root ) ; svg . mm . fit ( ) ;
57+ }
58+ }
59+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
60+ const { Transformer, Markmap } = window . markmap ;
61+ const transformer = new Transformer ( ) ;
62+ const markdown = `\`\`\`markdown
63+ ---
64+ title: LeetCode Patterns Knowledge Graph (33 Problems) — API Kernels → Patterns → Problems 🎯
65+ markmap:
66+ colorFreezeLevel: 2
67+ maxWidth: 300
68+ ---
69+
70+ ## 🎯 如何使用這個思維導圖(快速)
71+ - **自上而下閱讀**: *API Kernel* → *Pattern* → *Problems* (鏈接)
72+ - **練習循環**: 實現模板 → 解決 2–3 個問題 → 重構為可重用的 \`solve(pattern_state_machine)\` 心智模型
73+ - **進度追蹤**
74+ - [ ] 先完成所有 **簡單** 題目
75+ - [ ] 然後是 **中等** 變體
76+ - [ ] 最後是 **困難** “邊界情況放大器”
77+
78+ ---
79+
80+ ## 🧠 API 核心(“引擎”)
81+ ### SubstringSlidingWindow — *一維窗口狀態機*
82+ - ==核心不變性==: 窗口 \`[L,R]\` 通過 **向右擴展** + **向左收縮** 保持有效
83+ - 複雜度: 通常 $O(n)$ 時間,$O(\\Sigma)$ 空間(字母表 / 不同鍵)
84+
85+ <!-- markmap: fold -->
86+ #### 模式速查表(來自文檔)
87+ | 問題 | 不變性 | 狀態 | 窗口大小 | 目標 |
88+ |---------|-----------|-------|-------------|------|
89+ | [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py) | 全部唯一 | 最後索引映射 | 可變 | 最大 |
90+ | [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 不同 | 頻率映射 | 可變 | 最大 |
91+ | [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) | 覆蓋 \`t\` | 需要/擁有 | 可變 | 最小 |
92+ | [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py) | 精確頻率匹配 | 頻率 + 匹配 | 固定 | 存在 |
93+ | [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py) | 精確頻率匹配 | 頻率 + 匹配 | 固定 | 全部 |
94+ | [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py) | 和 ≥ 目標 | 整數和 | 可變 | 最小 |
95+
96+ #### 模式
97+ - **sliding_window_unique** *(最大化,“跳左”優化)*
98+ - 🎯 問題
99+ - [ ] [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py)
100+ - 關鍵狀態: \`last_seen[char]\` → \`L = max(L, last_seen[c]+1)\`
101+ - **sliding_window_at_most_k_distinct** *(最大化,無效時收縮)*
102+ - 🎯 問題
103+ - [ ] [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)
104+ - 關鍵不變性: \`len(freq) <= k\`
105+ - **sliding_window_freq_cover** *(覆蓋 / 精確匹配家族)*
106+ - 🎯 問題
107+ - [ ] [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) — *在有效時最小化*
108+ - [ ] [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py) — *固定窗口,收集索引*
109+ - [ ] [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py) — *固定窗口,布林值*
110+ - **sliding_window_cost_bounded** *(數值約束)*
111+ - 🎯 問題
112+ - [ ] [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py)
113+ - 典型要求: 正數 → 單調收縮有效
114+
115+ ---
116+
117+ ### TwoPointersTraversal — *序列上的指針編排*
118+ - ==核心不變性==: 指針確定性移動;已處理區域是“安全”的
119+ - 複雜度: 通常 $O(n)$ 時間,$O(1)$ 空間(排序步驟除外)
120+
121+ #### 模式比較(來自文檔)
122+ | 模式 | 指針初始化 | 移動 | 終止 | 時間 | 空間 | 關鍵用例 |
123+ |---------|--------------|----------|-------------|------|-------|--------------|
124+ | 相反方向 | \`0, n-1\` | 向中心 | \`L>=R\` | $O(n)$ | $O(1)$ | 排序對 / 回文 / 最大化 |
125+ | 同方向 | \`write, read\` | 向前 | \`read==n\` | $O(n)$ | $O(1)$ | 就地修改 |
126+ | 快慢指針 | \`slow, fast\` | 1× / 2× | 相遇或空 | $O(n)$ | $O(1)$ | 循環 / 中點 |
127+ | 去重枚舉 | \`i\` + \`L,R\` | 嵌套 | 完成 | $O(n^2)$ | $O(1)$ | 3Sum/4Sum |
128+
129+ #### 模式
130+ - **two_pointer_opposite_maximize**
131+ - 🎯 問題
132+ - [ ] [LeetCode 11 - Container With Most Water](https://github.com/lufftw/neetcode/blob/main/solutions/0011_container_with_most_water.py)
133+ - 洞察: 移動 **較短** 高度的指針
134+ - **two_pointer_three_sum** *(去重枚舉)*
135+ - 🎯 問題
136+ - [ ] [LeetCode 15 - 3Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0015_3sum.py)
137+ - [ ] [LeetCode 16 - 3Sum Closest](https://github.com/lufftw/neetcode/blob/main/solutions/0016_3sum_closest.py)
138+ - 要求: 先排序 ($O(n\\log n)$),然後掃描去重
139+ - **two_pointer_opposite_palindrome**
140+ - 🎯 問題
141+ - [ ] [LeetCode 125 - Valid Palindrome](https://github.com/lufftw/neetcode/blob/main/solutions/0125_valid_palindrome.py)
142+ - [ ] [LeetCode 680 - Valid Palindrome II](https://github.com/lufftw/neetcode/blob/main/solutions/0680_valid_palindrome_ii.py)
143+ - **two_pointer_writer_dedup**
144+ - 🎯 問題
145+ - [ ] [LeetCode 26 - Remove Duplicates from Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0026_remove_duplicates_from_sorted_array.py)
146+ - [ ] [LeetCode 80 - Remove Duplicates from Sorted Array II](https://github.com/lufftw/neetcode/blob/main/solutions/0080_remove_duplicates_from_sorted_array_ii.py)
147+ - **two_pointer_writer_remove**
148+ - 🎯 問題
149+ - [ ] [LeetCode 27 - Remove Element](https://github.com/lufftw/neetcode/blob/main/solutions/0027_remove_element.py)
150+ - **two_pointer_writer_compact**
151+ - 🎯 問題
152+ - [ ] [LeetCode 283 - Move Zeroes](https://github.com/lufftw/neetcode/blob/main/solutions/0283_move_zeroes.py)
153+
154+ ---
155+
156+ ### FastSlowPointers — *Floyd + 中點 + 隱式序列*
157+ - ==核心不變性==: 如果存在循環,\`fast\` 會遇到 \`slow\`
158+ - 模式
159+ - **fast_slow_cycle_detect**
160+ - [ ] [LeetCode 141 - Linked List Cycle](https://github.com/lufftw/neetcode/blob/main/solutions/0141_linked_list_cycle.py)
161+ - **fast_slow_cycle_start**
162+ - [ ] [LeetCode 142 - Linked List Cycle II](https://github.com/lufftw/neetcode/blob/main/solutions/0142_linked_list_cycle_ii.py)
163+ - **fast_slow_midpoint**
164+ - [ ] [LeetCode 876 - Middle of the Linked List](https://github.com/lufftw/neetcode/blob/main/solutions/0876_middle_of_the_linked_list.py)
165+ - **fast_slow_implicit_cycle**
166+ - [ ] [LeetCode 202 - Happy Number](https://github.com/lufftw/neetcode/blob/main/solutions/0202_happy_number.py)
167+
168+ ---
169+
170+ ### TwoPointerPartition — *就地分區“迷你快速排序”*
171+ - ==核心不變性==: 區域按屬性分區
172+ - 模式
173+ - **dutch_flag_partition**
174+ - [ ] [LeetCode 75 - Sort Colors](https://github.com/lufftw/neetcode/blob/main/solutions/0075_sort_colors.py)
175+ - **two_way_partition**
176+ - [ ] [LeetCode 905 - Sort Array By Parity](https://github.com/lufftw/neetcode/blob/main/solutions/0905_sort_array_by_parity.py)
177+ - [ ] [LeetCode 922 - Sort Array By Parity II](https://github.com/lufftw/neetcode/blob/main/solutions/0922_sort_array_by_parity_ii.py)
178+ - **quickselect_partition** *(通過分區選擇)*
179+ - [ ] [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py)
180+
181+ ---
182+
183+ ### MergeSortedSequences — *合併兩個排序序列*
184+ - ==核心不變性==: 輸出前綴完全排序
185+ - 模式
186+ - **merge_two_sorted_lists**
187+ - [ ] [LeetCode 21 - Merge Two Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0021_merge_two_sorted_lists.py)
188+ - **merge_two_sorted_arrays**
189+ - [ ] [LeetCode 88 - Merge Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0088_merge_sorted_array.py)
190+ - **merge_sorted_from_ends**
191+ - [ ] [LeetCode 977 - Squares of a Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0977_squares_of_a_sorted_array.py)
192+
193+ ---
194+
195+ ### KWayMerge — *合併 K 個排序序列*
196+ - 兩種主要實現
197+ - **merge_k_sorted_heap** → $O(N\\log k)$ 時間,$O(k)$ 堆
198+ - **merge_k_sorted_divide** → $O(N\\log k)$ 時間,有時較小的常數
199+ - 🎯 問題
200+ - [ ] [LeetCode 23 - Merge k Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0023_merge_k_sorted_lists.py)
201+ - 相關“混合思維”: [LeetCode 4 - Median of Two Sorted Arrays](https://github.com/lufftw/neetcode/blob/main/solutions/0004_median_of_two_sorted_arrays.py)
202+
203+ ---
204+
205+ ### HeapTopK — *在流式更新中保持最佳 K*
206+ - 模式
207+ - **heap_kth_element**
208+ - [ ] [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py)
209+
210+ ---
211+
212+ ### LinkedListInPlaceReversal — *指針手術*
213+ - 模式
214+ - **linked_list_k_group_reversal**
215+ - [ ] [LeetCode 25 - Reverse Nodes in k-Group](https://github.com/lufftw/neetcode/blob/main/solutions/0025_reverse_nodes_in_k_group.py)
216+ - 也包括核心鏈表運算
217+ - [ ] [LeetCode 2 - Add Two Numbers](https://github.com/lufftw/neetcode/blob/main/solutions/0002_add_two_numbers.py)
218+
219+ ---
220+
221+ ### BacktrackingExploration — *帶修剪的搜索樹*
222+ - 模式
223+ - **backtracking_n_queens**
224+ - [ ] [LeetCode 51 - N-Queens](https://github.com/lufftw/neetcode/blob/main/solutions/0051_n_queens.py)
225+
226+ ---
227+
228+ ### GridBFSMultiSource — *網格上的波前傳播*
229+ - 模式
230+ - **grid_bfs_propagation**
231+ - [ ] [LeetCode 994 - Rotting Oranges](https://github.com/lufftw/neetcode/blob/main/solutions/0994_rotting_oranges.py)
232+ - 實現不變性: 隊列持有當前“分鐘/層級”的前沿
233+
234+ ---
235+
236+ ## 🧭 路線圖切片(接下來要做什麼)
237+ ### 滑動窗口精通 📚
238+ - [ ] [LeetCode 3 - Longest Substring Without Repeating Characters](https://github.com/lufftw/neetcode/blob/main/solutions/0003_longest_substring_without_repeating_characters.py)
239+ - [ ] [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)
240+ - [ ] [LeetCode 209 - Minimum Size Subarray Sum](https://github.com/lufftw/neetcode/blob/main/solutions/0209_minimum_size_subarray_sum.py)
241+ - [ ] [LeetCode 567 - Permutation in String](https://github.com/lufftw/neetcode/blob/main/solutions/0567_permutation_in_string.py)
242+ - [ ] [LeetCode 438 - Find All Anagrams in a String](https://github.com/lufftw/neetcode/blob/main/solutions/0438_find_all_anagrams_in_a_string.py)
243+ - [ ] [LeetCode 76 - Minimum Window Substring](https://github.com/lufftw/neetcode/blob/main/solutions/0076_minimum_window_substring.py) 🔥
244+
245+ ### 雙指針精通 ⚡
246+ - 相反指針
247+ - [ ] [LeetCode 11 - Container With Most Water](https://github.com/lufftw/neetcode/blob/main/solutions/0011_container_with_most_water.py)
248+ - [ ] [LeetCode 125 - Valid Palindrome](https://github.com/lufftw/neetcode/blob/main/solutions/0125_valid_palindrome.py)
249+ - [ ] [LeetCode 680 - Valid Palindrome II](https://github.com/lufftw/neetcode/blob/main/solutions/0680_valid_palindrome_ii.py)
250+ - 寫指針(就地)
251+ - [ ] [LeetCode 26 - Remove Duplicates from Sorted Array](https://github.com/lufftw/neetcode/blob/main/solutions/0026_remove_duplicates_from_sorted_array.py)
252+ - [ ] [LeetCode 27 - Remove Element](https://github.com/lufftw/neetcode/blob/main/solutions/0027_remove_element.py)
253+ - [ ] [LeetCode 283 - Move Zeroes](https://github.com/lufftw/neetcode/blob/main/solutions/0283_move_zeroes.py)
254+ - [ ] [LeetCode 80 - Remove Duplicates from Sorted Array II](https://github.com/lufftw/neetcode/blob/main/solutions/0080_remove_duplicates_from_sorted_array_ii.py)
255+ - 快慢指針
256+ - [ ] [LeetCode 141 - Linked List Cycle](https://github.com/lufftw/neetcode/blob/main/solutions/0141_linked_list_cycle.py)
257+ - [ ] [LeetCode 142 - Linked List Cycle II](https://github.com/lufftw/neetcode/blob/main/solutions/0142_linked_list_cycle_ii.py)
258+ - [ ] [LeetCode 876 - Middle of the Linked List](https://github.com/lufftw/neetcode/blob/main/solutions/0876_middle_of_the_linked_list.py)
259+ - [ ] [LeetCode 202 - Happy Number](https://github.com/lufftw/neetcode/blob/main/solutions/0202_happy_number.py)
260+
261+ ---
262+
263+ ## 🧩 “同一問題,不同視角” (遷移學習)
264+ - **選擇**: [LeetCode 215 - Kth Largest Element in an Array](https://github.com/lufftw/neetcode/blob/main/solutions/0215_kth_largest_element_in_an_array.py)
265+ - 選項 A: \`quickselect_partition\` (期望 $O(n)$)
266+ - 選項 B: \`heap_kth_element\` ($O(n\\log k)$,流式友好)
267+ - **合併**:
268+ - 2 路: [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)
269+ - K 路: [LeetCode 23 - Merge k Sorted Lists](https://github.com/lufftw/neetcode/blob/main/solutions/0023_merge_k_sorted_lists.py)
270+ - “邊界 + 合併思維”: [LeetCode 4 - Median of Two Sorted Arrays](https://github.com/lufftw/neetcode/blob/main/solutions/0004_median_of_two_sorted_arrays.py)
271+
272+ ---
273+
274+ ## 🧱 最小可重用模板(心智 API)
275+ \`\`\`python
276+ # 滑動窗口(可變,最大化)
277+ def max_window(seq):
278+ state = {}
279+ L = 0
280+ ans = 0
281+ for R, x in enumerate(seq):
282+ add(state, x)
283+ while invalid(state):
284+ remove(state, seq[L]); L += 1
285+ ans = max(ans, R - L + 1)
286+ return ans
287+
288+ # 雙指針(相反)
289+ def opposite(arr):
290+ L, R = 0, len(arr) - 1
291+ while L < R:
292+ if should_move_left(arr, L, R):
293+ L += 1
294+ else:
295+ R -= 1
296+ \`\`\`
297+
298+ ---
299+ \`\`\`` ;
300+ const { root } = transformer . transform ( markdown ) ;
301+ const svg = d3 . select ( '.markmap' ) . append ( 'svg' ) ;
302+ const mm = Markmap . create ( svg . node ( ) , { color : ( node ) => node . payload ?. color || '#f59e0b' } , root ) ;
303+ svg . node ( ) . mm = mm ;
304+ if ( window . markmap && window . markmap . Toolbar ) {
305+ const toolbar = new window . markmap . Toolbar ( ) ;
306+ toolbar . attach ( mm ) ;
307+ setTimeout ( function ( ) {
308+ document . querySelectorAll ( '.mm-toolbar' ) . forEach ( function ( toolbar ) {
309+ toolbar . querySelectorAll ( '.mm-toolbar-item' ) . forEach ( function ( item ) {
310+ if ( ( item . title || '' ) . toLowerCase ( ) . includes ( 'dark' ) ) item . remove ( ) ;
311+ } ) ;
312+ var brand = toolbar . querySelector ( '.mm-toolbar-brand' ) ;
313+ if ( brand ) {
314+ brand . innerHTML = '🟡 NeetCode' ;
315+ brand . href = '#' ; brand . onclick = function ( e ) { e . preventDefault ( ) ; } ;
316+ brand . style . fontSize = '12px' ; brand . style . color = '#666' ;
317+ }
318+ } ) ;
319+ } , 200 ) ;
320+ }
321+ } ) ;
322+ </ script >
323+ </ head >
324+ < body >
325+ < div id ="topbar ">
326+ < button onclick ="fitView() "> Fit View</ button >
327+ < button onclick ="expandAll() "> Expand All</ button >
328+ < button onclick ="collapseAll() "> Collapse All</ button >
329+ </ div >
330+ < div class ="markmap "> </ div >
331+ </ body >
332+ </ html >
0 commit comments