題目描述
題目轉載自Leetcode
輸入一棵二叉樹的根節點,求該樹的深度。從根節點到葉節點依次經過的節點(含根、葉節點)形成樹的一條路徑,最長路徑的長度爲樹的深度。
例如:
給定二叉樹 [3,9,20,null,null,15,7],
返回它的最大深度 3 。
提示:
節點總數 <= 10000
題解
方法一:後序遍歷(DFS)
樹的後序遍歷 / 深度優先搜索往往利用 遞歸 或 棧 實現,本文使用遞歸實現。
關鍵點: 此樹的深度和其左(右)子樹的深度之間的關係。顯然,此樹的深度 等於 左子樹的深度 與 右子樹的深度 中的 最大值 +1 。
算法解析:
終止條件: 當 root 爲空,說明已越過葉節點,因此返回 深度 0 。遞推工作: 本質上是對樹做後序遍歷。
計算節點 root 的 左子樹的深度 ,即調用 maxDepth(root.left);
計算節點 root 的 右子樹的深度 ,即調用 maxDepth(root.right);
返回值: 返回 此樹的深度 ,即 max(maxDepth(root.left), maxDepth(root.right)) + 1。
複雜度分析:
時間複雜度 O(N):N 爲樹的節點數量,計算樹的深度需要遍歷所有節點。
空間複雜度 O(N) : 最差情況下(當樹退化爲鏈表時),遞歸深度可達到 N 。
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
方法二:層序遍歷(BFS)
樹的層序遍歷 / 廣度優先搜索往往利用 隊列 實現。
關鍵點: 每遍歷一層,則計數器 +1 ,直到遍歷完成,則可得到樹的深度。
算法解析:
特例處理: 當 root 爲空,直接返回 深度 0 。
初始化: 隊列 queue (加入根節點 root ),計數器 res = 0。
循環遍歷: 當 queue 爲空時跳出。
初始化一個空列表 tmp ,用於臨時存儲下一層節點;
遍歷隊列: 遍歷 queue 中的各節點 node ,並將其左子節點和右子節點加入 tmp;
更新隊列: 執行 queue = tmp ,將下一層節點賦值給 queue;
統計層數: 執行 res += 1 ,代表層數加 1;
返回值: 返回 res 即可。
複雜度分析:
時間複雜度 O(N) : N 爲樹的節點數量,計算樹的深度需要遍歷所有節點。
空間複雜度 O(N) : 最差情況下(當樹平衡時),隊列 queue 同時存儲 N/2 個節點。
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
//LinkedList當做隊列使用add()方法添加元素
List<TreeNode> queue = new LinkedList<>() {{ add(root); }}, tmp;
int res = 0;
while(!queue.isEmpty()) {
tmp = new LinkedList<>();
for(TreeNode node : queue) {
if(node.left != null) tmp.add(node.left);
if(node.right != null) tmp.add(node.right);
}
queue = tmp;
res++;
}
return res;
}
}