二叉树_题目1:543. 二叉树的直径

54 阅读2分钟

题目1:543. 二叉树的直径

543. 二叉树的直径

本题可转变成递归求二叉树深度

同类题目

124. 二叉树中的最大路径和

前置知识

题目描述

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

二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 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…