Leetcode 題目多樣,尤其是「二元樹(Binary Tree)」相關題型,容易讓人看了發愣。
本篇文章將教你如何釐清解法邏輯,並將二元樹題型拆解為兩大類解題策略,搭配範例與模板,幫助你用 DFS(深度優先搜尋)更系統地解題
類型一:遍歷型(Traversal Type)
這類題目需要「走過整棵樹的所有節點」,通常是為了計算某種總量,例如:
解題思路
可根據需求使用:
- 後序遍歷 + 回傳值 return → 適合需要組合子樹結果的情況
- 前序遍歷 + 狀態變數追蹤 → 適合需要累加或記錄路徑狀態的情況
模板(後序 + return)
1 2 3 4 5 6
| function dfs(node) { if (node === null) return baseValue; const left = dfs(node.left); const right = dfs(node.right); return combine(left, right, node); }
|
模板(前序 + 狀態變數)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let result = 0; let pathDepth = 0;
function traverse(node) { if (node === null) return;
pathDepth++; if (node.left === null && node.right === null) { result = Math.max(result, pathDepth); }
traverse(node.left); traverse(node.right);
pathDepth--; }
|
Maximum Depth of Binary Tree
題目連結:104. Maximum Depth of Binary Tree
題目描述:
給定一棵二元樹,請求出它的「最大深度」——也就是從根節點走到最遠的葉子節點所需經過的節點數量。
解題思路:使用前序遍歷 + 狀態變數追蹤
使用 depth 追蹤當前所在第幾層
每遇到一個葉子節點,就與 result
比較並更新最大值
所有節點遍歷完畢後,result
即為最大深度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
var maxDepth = function(root) { let depth = 0 let result = 0 const traverse = (node) =>{ if(node === null) return depth++ if(node.left === null && node.right === null){ result = Math.max(result, depth) } traverse(node.left) traverse(node.right) depth-- } traverse(root) return result
};
|
第二類: Comparison 型 - 比較兩棵/兩節點
這類題目不再只是單純遍歷,而是需要「比較兩個節點的結構與數值是否一致」,例如:
- 判斷兩棵樹是否相同(Same Tree)
- 判斷是否為對稱樹(Symmetric Tree)
解題思路
- 同步比較兩個節點
p
與 q
- 確認三件事:
- 是否都為
null
- 是否有一個是
null
(另一個不是)
- 兩節點的值是否相等
- 最後遞迴比對左子樹與右子樹是否一致
1 2 3 4 5 6
| function compare(p, q) { if (p === null && q === null) return true; if (p === null || q === null) return false; if (p.val !== q.val) return false; return compare(p.left, q.left) && compare(p.right, q.right); }
|
呼應 Maximum Depth of Binary Tree
1 2 3 4 5 6 7
| var maxDepth = function(root) { if (!root) return 0; let leftMax = maxDepth(root.left); let rightMax = maxDepth(root.right); return 1 + Math.max(leftMax, rightMax); };
|