Easy
题目描述
给定一棵二叉树的根节点,返回该树的直径长度。
二叉树的直径是指树中任意两个节点之间最长路径的长度。这条路径可能穿过也可能不穿过根节点。
两节点之间的路径长度是以它们之间边的数目表示。
示例 1:
输入:root = [1,2,3,4,5]
输出:3
解释:3是路径 [4,2,1,3] 或者 [5,2,1,3] 的长度。
示例 2:
输入:root = [1,2]
输出:1
提示:
- 树中节点数目在范围 [1, 10^4] 内
- -100 <= Node.val <= 100
解题思路
这道题的关键在于理解二叉树的直径实际上是任意两个节点之间的最长路径。
核心思路: 对于任意一个节点,经过该节点的最长路径等于其左子树的深度加上右子树的深度。因此,我们需要遍历每个节点,计算经过该节点的最长路径,并维护全局最大值。
算法步骤:
- 使用深度优先搜索(DFS)递归遍历树的每个节点
- 对于每个节点,计算其左子树和右子树的最大深度
- 经过当前节点的最长路径长度 = 左子树深度 + 右子树深度
- 更新全局直径最大值
- 返回当前节点的最大深度(用于上层递归)
优化点: 我们可以在计算树深度的同时更新直径,这样只需要一次DFS遍历,时间复杂度为O(n)。每个节点访问一次,空间复杂度主要由递归栈决定,为O(h),其中h是树的高度。
代码实现
class Solution {
public:
int diameterOfBinaryTree(TreeNode* root) {
int diameter = 0;
maxDepth(root, diameter);
return diameter;
}
private:
int maxDepth(TreeNode* node, int& diameter) {
if (!node) return 0;
int leftDepth = maxDepth(node->left, diameter);
int rightDepth = maxDepth(node->right, diameter);
diameter = max(diameter, leftDepth + rightDepth);
return max(leftDepth, rightDepth) + 1;
}
};
class Solution:
def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
self.diameter = 0
def max_depth(node):
if not node:
return 0
left_depth = max_depth(node.left)
right_depth = max_depth(node.right)
self.diameter = max(self.diameter, left_depth + right_depth)
return max(left_depth, right_depth) + 1
max_depth(root)
return self.diameter
public class Solution {
private int diameter = 0;
public int DiameterOfBinaryTree(TreeNode root) {
MaxDepth(root);
return diameter;
}
private int MaxDepth(TreeNode node) {
if (node == null) return 0;
int leftDepth = MaxDepth(node.left);
int rightDepth = MaxDepth(node.right);
diameter = Math.Max(diameter, leftDepth + rightDepth);
return Math.Max(leftDepth, rightDepth) + 1;
}
}
var diameterOfBinaryTree = function(root) {
let diameter = 0;
function maxDepth(node) {
if (!node) return 0;
const leftDepth = maxDepth(node.left);
const rightDepth = maxDepth(node.right);
diameter = Math.max(diameter, leftDepth + rightDepth);
return Math.max(leftDepth, rightDepth) + 1;
}
maxDepth(root);
return diameter;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 每个节点只访问一次,n为节点数量 |
| 空间复杂度 | O(h) | 递归栈的深度,h为树的高度,最坏情况下为O(n) |