欢迎光临
我们一直在努力

【二叉树-5】543.二叉树的直径

题目描述:

给你一棵二叉树的根节点,返回该树的 直径 。

二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。

两节点之间路径的 长度 由它们之间边数表示。

示例 1:

输入:root = [1,2,3,4,5]
输出:3
解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。

示例 2:

输入:root = [1,2]
输出:1

解题思路

方法一:递归法(后序遍历)

核心思路:

对于任意节点,经过它的最长路径 = 左子树深度 + 右子树深度

直径 = max(左子树深度 + 右子树深度)

注意:

  • 深度是节点数,边数 = 节点数 – 1

  • 但 左深度 + 右深度 正好等于边数(因为左右各一条边连接到当前节点)

具体过程示例:

1
/ \\
2 3
/ \\
4 5

节点1: 左深度=2, 右深度=1 → 路径=2+1=3
节点2: 左深度=1, 右深度=1 → 路径=1+1=2
节点4: 左深度=0, 右深度=0 → 路径=0+0=0
节点5: 左深度=0, 右深度=0 → 路径=0+0=0
节点3: 左深度=0, 右深度=0 → 路径=0+0=0

最大直径 = 3 ✅

代码实现:

class Solution {
public:
int diameter = 0; // 全局变量记录最大直径

int diameterOfBinaryTree(TreeNode* root) {
depth(root);
return diameter;
}

private:
int depth(TreeNode* node) {
if (node == nullptr) return 0;

int leftDepth = depth(node->left);
int rightDepth = depth(node->right);

// 更新最大直径:经过当前节点的路径
diameter = max(diameter, leftDepth + rightDepth);

// 返回当前节点的深度
return max(leftDepth, rightDepth) + 1;
}
};

复杂度分析:

维度复杂度说明
时间复杂度 O(n) 每个节点访问一次
空间复杂度 O(h) 递归栈深度,h 是树的高度

空间复杂度说明:

  • 最坏情况(链状树):O(n)

  • 平均情况(平衡树):O(log n)

关键细节:

1. 为什么 leftDepth + rightDepth 就是边数?

1
/ \\
2 3
/ \\
4 5

节点1的左深度 = 2(路径 1→2→4,边数2)
节点1的右深度 = 1(路径 1→3,边数1)
经过节点1的路径 = 4→2→1→3,边数 = 2+1 = 3

左深度 = 左子树的边数,右深度 = 右子树的边数,加起来就是经过当前节点的总边数。

2. 为什么用全局变量 diameter?

因为最大直径不一定经过根节点,需要遍历所有节点,取最大值。

  • depth 函数返回的是深度(用于上层计算)

  • diameter 记录的是全局最大直径

3. 和「最大深度」的区别
题目区别
104. 最大深度 返回 max(left, right) + 1
543. 直径 额外更新 diameter = max(diameter, left + right)

543 题在 104 题的基础上,多了一步更新直径。

方法二:迭代法(不推荐)

用栈模拟后序遍历,记录每个节点的深度和直径。代码复杂,不推荐。

两种方法对比:

方法时间复杂度空间复杂度代码复杂度推荐度
递归(后序) O(n) O(h) 简单 ⭐⭐⭐⭐⭐
迭代(栈) O(n) O(n) 复杂 ⭐⭐

总结:

要点说明
核心思想 经过节点的路径 = 左深度 + 右深度
递归公式 diameter = max(diameter, left + right)
返回值 max(left, right) + 1(深度)
时间复杂度 O(n)
空间复杂度 O(h)
赞(0)
未经允许不得转载:171主机测评 » 【二叉树-5】543.二叉树的直径
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址