二叉树——二叉树的直径
题目:
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
两节点之间路径的 长度 由它们之间边数表示。
核心思路:
- 二叉树直径定义:任意两节点间最长路径的边数,路径可能不经过根节点。
- 关键转化:
- 一个节点的**左子树高度+右子树高度 **= 以该节点为中心的路径长度
- 整棵树的直径 = 所有节点[左高+右高]的最大值
- 递归方案:
- 后序遍历递归计算每个节点的左右子树高度
- 遍历过程中实时更新最大直径
- 最终返回最大直径
完整代码实现如下:
// 二叉树节点定义
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
class Solution {
// 全局变量,记录最大直径
int maxDiameter = 0;
public int diameterOfBinaryTree(TreeNode root) {
// 递归计算高度,同时更新最大直径
height(root);
return maxDiameter;
}
// 递归计算节点高度:高度 = 左右子树最大高度 + 1
private int height(TreeNode node) {
// 空节点高度为0
if (node == null) {
return 0;
}
// 递归计算左、右子树高度
int leftHeight = height(node.left);
int rightHeight = height(node.right);
// 更新最大直径:当前节点的路径长度 = 左高 + 右高
maxDiameter = Math.max(maxDiameter, leftHeight + rightHeight);
// 返回当前节点的高度(供父节点使用)
return Math.max(leftHeight, rightHeight) + 1;
}
}
代码解释:
- TreeNode 类:标准二叉树节点结构,包含值、左孩子、右孩子。
- maxDiameter:全局变量,实时记录遍历过程中找到的最长路径。
- diameterOfBinaryTree 方法:主方法,调用递归函数后返回结果。
- height 递归方法:
- 终止条件:空节点返回高度 0
- 递归计算左右子树高度
- 用左高+右高更新最大直径
- 返回当前节点的高度(用于上层递归计算)
复杂度分析
- 时间复杂度:O (n) —— 每个节点仅遍历一次
- 空间复杂度:O (h) —— h 为树的高度,递归调用栈的深度
特别注意一点
递归的返回值是当前节点的高度,并不是我们所要的路径长度,而是用于上层递归计算最大直径所需要的左右子树高度和,因此在主函数中,我们只是调用了递归height(root),而没有接收其返回值,而是返回递归调用中实时记录的最大路径长度(maxDiameter)
- 递归返回高度时必须+1(因为高度时顶点数)
- 计算直径时不加1
即 - 高度:算的是顶点数(所以要+1)
- 直径:直接用左右高度相加,就是边数(不用+1)
总结:
- 二叉树直径 = 所有节点的左子树高度 + 右子树高度的最大值
- 用后序递归一次遍历完成「高度计算」和「直径更新」
- 时间复杂度最优 O (n),代码简洁高效
浙公网安备 33010602011771号