题目1:543. 二叉树的直径
本题可转变成递归求二叉树深度
同类题目
前置知识
- 无
题目描述
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
两节点之间路径的 长度 由它们之间边数表示。
示例 1:
输入:root = [1,2,3,4,5]
输出:3
解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。
示例 2:
输入:root = [1,2]
输出:1
提示:
- 树中节点数目在范围
[1, 104]内 -100 <= Node.val <= 100
思路分析
本题中要求的是二叉树的直径的最大值,所谓二叉树的直径就是左右子树的最大深度之和,那么最大直径即使要从深度之和中选择一个最大值。
对每个节点计算左右子树的深度,在计算深度的过程中可以顺便计算最大直径。这样可以把该题分解为求左右子树最大深度问题,那么计算直径的位置应该是计算出左右子树的最大深度之后,即后序遍历的位置。
针对二叉树的题目,可以有3个位置嵌入代码,这三个位置分别是前序位置、中序位置和后序位置。你可以在这3个为置嵌入巧妙的代码逻辑来完成题目的需求。
有了这个遍历框架之后,你只需要考虑当前节点应该做什么即可,其它交给框架。
void traverse(TreeNode root) {
if (root == null) {
return;
}
// 前序位置
traverse(root.left);
// 中序位置
traverse(root.right);
// 后序位置
}
程序代码
//https://leetcode.cn/problems/diameter-of-binary-tree/description/
//543. 二叉树的直径
#include<iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
private:
// 使用一个全局变量记录直径的最大值
int res = 0;
public:
int getDiameter(TreeNode* root)
{
if(root == NULL)
{
return 0;
}
int leftlen = getDiameter(root->left);
int rightlen = getDiameter(root->right);
// 这个树的最大直径为:每一个树节点的左子树深度+右子树深度 的最大值
res = max(leftlen + rightlen,res);
// 返回当前节点的最大深度
return 1 + max(leftlen,rightlen);
}
int diameterOfBinaryTree(TreeNode* root) {
getDiameter(root);
// 注意这里反馈的不是由getDiameter 返回的值
return res;
}
};
题目感悟
- 直径到深度的转换
- 深度求解的一种思路是分解为求左右子树的深度(后序位置)
更多相关知识:github.com/pingguo1987…