Back to Blog
5 min read
1.2k views
Tree 是 NeetCode 150 裡面被標注「🔥🔥 Super Important」的主題。幾乎所有 Tree 題都可以用遞迴(DFS)解——但「遞迴」對很多人來說是個謎。這篇用三道題,把遞迴的思維方式說清楚:你只需要定義好「這個函式做什麼」,然後信任它對子節點也成立。
Binary Tree 的結構
每個節點最多有兩個子節點(left 和 right)。沒有子節點的叫葉節點(Leaf)。
3
9
left
20
right
None None
15
7
Python 的 TreeNode 定義(LeetCode 固定格式)
DFS 遞迴的思維方式
寫 Tree 遞迴題時,很多人的錯誤是「試圖在腦中追蹤所有層的執行過程」——這是不可能的,也不需要。
正確的思維:
1
定義清楚:這個函式「對一個 node」做什麼、回傳什麼2
寫好 base case:node 是 None 時怎麼辦3
假設:左子樹和右子樹已經得到了正確答案(信任遞迴)4
組合:把左右子樹的答案組合成當前 node 的答案#104 Maximum Depth of Binary Tree
一棵 Binary Tree 的「最大深度」= 從 root 到最遠葉節點的層數。
Input / Output
套入思維框架:
1. 函式定義maxDepth(node) 回傳以 node 為根的子樹最大深度
2. Base casenode 是 None → 深度是 0
3. 信任遞迴左子樹深度 = maxDepth(node.left),右子樹深度 = maxDepth(node.right)
4. 組合答案當前節點的深度 = max(左深, 右深) + 1(加上自己這層)
#104 Maximum Depth of Binary Tree
⏱ Time: O(n)💾 Space: O(h) h=樹高,遞迴呼叫棧深度
遞迴展開過程(上面的範例):
maxDepth(3)
→ maxDepth(9) = max(0,0)+1 = 1
→ maxDepth(20)
→ maxDepth(15) = max(0,0)+1 = 1
→ maxDepth(7) = max(0,0)+1 = 1
→ maxDepth(20) = max(1,1)+1 = 2
→ maxDepth(3) = max(1,2)+1 = 3 ✅
#100 Same Tree
判斷兩棵樹是否完全相同(結構和值都一樣)。
Input / Output
套入思維框架:
Base casep 和 q 都是 None → True;其中一個是 None → False
信任遞迴isSameTree(p.left, q.left) 和 isSameTree(p.right, q.right)
組合答案當前節點值相同 AND 左子樹相同 AND 右子樹相同
#100 Same Tree
⏱ Time: O(n)💾 Space: O(h)
#226 Invert Binary Tree
把每個節點的左右子樹互換,遞迴翻轉整棵樹。
Input / Output
套入思維框架:
Base casenode 是 None → 直接回傳 None
信任遞迴invertTree(node.left) 回傳翻轉後的左子樹;invertTree(node.right) 同理
組合答案把兩個翻轉後的子樹交叉接回:node.left = 翻轉右,node.right = 翻轉左
#226 Invert Binary Tree
⏱ Time: O(n)💾 Space: O(h)
或者用一行 Python 同時完成:
更簡潔的寫法
DFS 的三種遍歷順序
根據「何時處理當前節點」分成三種,只差一行的位置:
Pre / In / Post-order DFS
Preorder
root → left → right
Clone tree、Serialize tree
Inorder
left → root → right
BST → Sorted array(BST 的特性)
Postorder
left → right → root
Max Depth、Bottom-up 計算
遞迴寫 Tree 題的關鍵心態:不要試圖在腦中追蹤所有層的狀態。你只需要問:「如果左右子樹都已經給出了正確答案,我怎麼把它們組合起來?」這一步想清楚,剩下的交給 Python 的呼叫棧。
本篇重點整理
🌳Tree DFS = 遞迴,四步:定義、base case、信任遞迴、組合答案
📏Max Depth:max(左深, 右深) + 1,Postorder 思維
🪞Same Tree:值相同 AND 左子樹相同 AND 右子樹相同
🔄Invert:翻轉左右子樹後,交叉接回 root.left / root.right
📋Pre/In/Post-order 只差「何時 process(node)」,放的位置不同
LeetCode
Tree
DFS
Recursion
Python
EP.09