https://leetcode.cn/problems/diameter-of-binary-tree/description/
一、题目描述
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root
。
两节点之间路径的 长度 由它们之间边数表示。
二、相关知识点了解
二叉树是每个节点最多有两个子树的树结构,这两个子树通常被称为左子树和右子树。它的递归定义为:二叉树要么为空,要么由一个根节点(root)、一个左子树和一个右子树组成,左子树和右子树本身也是二叉树。
节点组成:一个典型的二叉树节点包含数据部分(用于存储实际的数据)、左子节点引用(指向左子树的根节点)和右子节点引用(指向右子树的根节点)。
层次结构:二叉树有明显的层次,根节点位于最高层(第 1 层),根节点的子节点位于第 2 层,以此类推。这种层次结构便于对二叉树进行遍历和操作。
如图:
三、实例分析
示例 :
输入:root = [1,2,3,4,5] 输出:3 解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。
这里的4结构就是{val:4 left:NULL right:NULL}(其中NULL表示为空也就是到达结束位置)
通过实例可知,今天这道题目让我们求的是从任意两个节点中最长路径的长度。
四、解题思路&代码实现
通过上述可以得知,要想求出从任意两个节点中最长路径的长度,可能会有两种。
第一种:可能会通过根节点,也就说起点在左子树终点在右子树。
第二种:也可能会不经过根节点,也就是在左子树或右子树中。(还有一种可能就是这个二叉树未必一定会有两个节点)
那么现在就又有一个新的问题,我们要怎么求出这个二叉树的深度呢?(这里所说的二叉树的深度指的是从根节点到最远叶子节点所经过的边的数量)这里我们选择用递归的方式来求出它的深度。
// 计算二叉树最大深度的函数
int maxDepth(struct TreeNode* root) {
// 如果当前节点为空,说明这是一个空树,深度为0
if (root == NULL)
return 0;
// 递归计算左子树的最大深度
int leftMax = maxDepth(root->left);
// 递归计算右子树的最大深度
int rightMax = maxDepth(root->right);
// 比较左子树和右子树的最大深度
// 取较大值,并加上当前节点这一层(所以加1)
return leftMax > rightMax? leftMax + 1 : rightMax + 1;
}
整体的思路就是分别求出根节点的左右子树的最大深度,最后通过比较得出最大的深度在左右那一边,最后再加上根节点就是二叉树的最大深度。
那么现在需要的就是,把我们分析的两种可能性编写成代码即可!
int diameterOfBinaryTree(struct TreeNode* root) {
// 如果根节点为空,二叉树的直径为0
if (root == NULL) {
return 0;
}
// 如果经过根节点
// 计算经过当前根节点的路径长度,即左子树深度 + 右子树深度
int mid = maxDepth(root->left) + maxDepth(root->right);
// 如果最长路径在左或右子树中
// 递归计算左子树的直径
int left = diameterOfBinaryTree(root->left);
// 递归计算右子树的直径
int right = diameterOfBinaryTree(root->right);
// 初始化最大直径为经过当前根节点的路径长度
int max = mid;
// 如果左子树的直径大于当前最大直径,则更新最大直径
if (max < left) {
max = left;
}
// 如果右子树的直径大于当前最大直径,则更新最大直径
else if (max < right) {
max = right;
}
// 返回最大直径
return max;
}
整体代码如下:
// 该函数用于计算二叉树的最大深度
int maxDepth(struct TreeNode* root) {
if (root == NULL) {
return 0;
}
int leftMax = maxDepth(root->left);
int rightMax = maxDepth(root->right);
return leftMax > rightMax? leftMax + 1 : rightMax + 1;
}
// 该函数用于计算二叉树的直径
int diameterOfBinaryTree(struct TreeNode* root) {
// 如果根节点为空,二叉树的直径为0
if (root == NULL) {
return 0;
}
// 计算经过当前根节点的路径长度,即左子树深度 + 右子树深度
int mid = maxDepth(root->left) + maxDepth(root->right);
// 递归计算左子树的直径
int left = diameterOfBinaryTree(root->left);
// 递归计算右子树的直径
int right = diameterOfBinaryTree(root->right);
// 初始化最大直径为经过当前根节点的路径长度
int max = mid;
// 如果左子树的直径大于当前最大直径,则更新最大直径
if (max < left) {
max = left;
}
// 如果右子树的直径大于当前最大直径,则更新最大直径
else if (max < right) {
max = right;
}
// 返回最大直径
return max;
}
五、题目总结
通过今天的题目,我们了解了二叉树这一数据结构,也通过了一个问题拆分成若干个子问题来帮助我们完成今天的这道题目。以上就是关于这个二叉树问题的全部分析了。如果后续你遇到类似的问题,或者对这一问题有了新的思考方向,都可以再次回顾我们的讨论内容。相信你在不断实践和思考中,能够轻松应对这类问题。谢谢大家!荆轲刺秦!!!