LeetcodeLeetCode
Maximum Depth of Binary Tree
Find the maximum depth of a binary tree using recursive traversal
Find the maximum number of nodes along the longest path from root to leaf
問題描述
給定一個二叉樹 root
,返回其最大深度。
二叉樹的 最大深度 是指從根節點到最遠葉子節點的最長路徑上的節點數。
範例
輸入:root = [3,9,20,null,null,15,7]
輸出:3
輸入:root = [1,null,2]
輸出:2
限制條件
- 樹中節點的數量在
[0, 10⁴]
範圍內 -100 <= Node.val <= 100
解題思路
遞歸分解
樹的最大深度 = max(左子樹深度, 右子樹深度) + 1
基礎情況
空節點的深度為 0
遞歸計算
分別計算左右子樹深度,取最大值加 1
解決方案
/**
* Definition for a binary tree node.
*/
export class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}
export function maxDepth(root: TreeNode | null): number {
// Base case: depth of empty node is 0
if (!root)
return 0;
// Recursively calculate depth of left and right subtrees
const leftDepth = maxDepth(root.left);
const rightDepth = maxDepth(root.right);
// Return the maximum depth + 1 (current node)
return Math.max(leftDepth, rightDepth) + 1;
}
import { describe, expect, it } from 'vitest';
import { maxDepth, TreeNode } from './solution';
describe('104. Maximum Depth of Binary Tree', () => {
function createTree(values: (number | null)[]): TreeNode | null {
if (!values.length)
return null;
const root = new TreeNode(values[0] as number);
const queue = [root];
let i = 1;
while (queue.length && i < values.length) {
const node = queue.shift()!;
// Left child
if (i < values.length && values[i] !== null) {
node.left = new TreeNode(values[i] as number);
queue.push(node.left);
}
i++;
// Right child
if (i < values.length && values[i] !== null) {
node.right = new TreeNode(values[i] as number);
queue.push(node.right);
}
i++;
}
return root;
}
it('should handle example case 1', () => {
const root = createTree([3, 9, 20, null, null, 15, 7]);
expect(maxDepth(root)).toBe(3);
});
it('should handle example case 2', () => {
const root = createTree([1, null, 2]);
expect(maxDepth(root)).toBe(2);
});
it('should handle empty tree', () => {
expect(maxDepth(null)).toBe(0);
});
it('should handle single node', () => {
const root = createTree([1]);
expect(maxDepth(root)).toBe(1);
});
it('should handle complete binary tree', () => {
const root = createTree([1, 2, 3, 4, 5, 6, 7]);
expect(maxDepth(root)).toBe(3);
});
});
深度優先搜索 (DFS)
這是樹遍歷問題的經典應用,使用遞歸的深度優先搜索。
核心思想
樹的深度等於左右子樹中較深的那個深度加 1(當前節點)。
遞歸結構
- 基礎情況:空節點深度為 0
- 遞歸情況:
max(左子樹深度, 右子樹深度) + 1
複雜度分析
- 時間複雜度: O(n) - 需要訪問每個節點一次
- 空間複雜度: O(h) - h 為樹的高度,遞歸調用棧的深度
在最壞情況下(完全不平衡的樹),空間複雜度為 O(n);在最好情況下(完全平衡的樹),空間複雜度為 O(log n)
執行過程示例
以樹 [3,9,20,null,null,15,7]
為例:
3
/ \
9 20
/ \
15 7
遞歸調用過程:
maxDepth(3)
= max(maxDepth(9)
,maxDepth(20)
) + 1maxDepth(9)
= max(maxDepth(null)
,maxDepth(null)
) + 1 = 0 + 0 + 1 = 1maxDepth(20)
= max(maxDepth(15)
,maxDepth(7)
) + 1maxDepth(15)
= 1,maxDepth(7)
= 1maxDepth(20)
= max(1, 1) + 1 = 2maxDepth(3)
= max(1, 2) + 1 = 3
迭代版本 (BFS)
function maxDepthIterative(root: TreeNode | null): number {
if (!root) return 0;
const queue: TreeNode[] = [root];
let depth = 0;
while (queue.length > 0) {
const levelSize = queue.length;
for (let i = 0; i < levelSize; i++) {
const node = queue.shift()!;
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
depth++;
}
return depth;
}
這個版本使用廣度優先搜索,逐層遍歷樹。
實際應用
- 文件系統:計算目錄的最大嵌套深度
- 組織結構:計算公司層級結構的深度
- 表達式樹:計算數學表達式的嵌套層數
- 決策樹:分析決策樹的複雜度
相關變體
- 最小深度:到最近葉子節點的距離
- 平衡檢查:檢查樹是否平衡(左右子樹高度差 ≤ 1)
- 直徑計算:樹中任意兩節點間的最長路徑