当前位置: 首页 > news >正文

LintCode第1181题-二叉树的直径

描述

给定一颗二叉树,您需要计算树的直径长度。 二叉树的直径是树中任意两个节点之间最长路径的长度.

样例 1:

给定一棵二叉树 1/ \2   3/ \     4   5    
返回3, 这是路径[4,2,1,3] 或者 [5,2,1,3]的长度.

样例 2:

输入:[2,3,#,1]
输出:2解释:2/3/
1

思路:该题要计算二叉树的高度 宽度等等一些列问题 优先想到遍历树的常用方法 深度优先搜索和广度优先搜索  而高度问题经常使用深度优先搜索 而深度优先搜索在二叉树中常用的具体方法就是前序遍历 中序遍历和后序遍历 (先序和后序对三叉树、N 叉树一样适用,只要孩子是有序的(List 顺序)。中序只在二叉树里有标准唯一的定义;对三叉/多叉树没有唯一的“中序”)

常见的适用于

后序遍历的情况有:子树高度、直径、是否平衡

中序遍历的情况有:二叉搜索树特别有用 或者二叉树得到有序队列

前序遍历的情况有:天然适合“序列化/复制结构”

对于该问题常用的解决方法有两种:

第一种好理解:

首先计算所有节点的左右子树高度

然后通过任意遍历(前序遍历,中序遍历,后序遍历都可以)

遍历所有节点 计算出最长的直径值 即为最终值

第二种速度快直观:直接使用后序遍历在遍历的同时 会计算出每一个节点的高度 会一次性的计算出该节点的直径值 即一次遍历即可求出最长的二叉树的直接(因为将第一种方法的两步放在一块了 原因是由于后序遍历的天然特性 在访问最终根节点前 左右子树的高度都已经被访问 即可以在访问根节点的同时拿到左右子树的高度)

先来第一种的代码:

代码如下:

/**

 * Definition of TreeNode:

 * public class TreeNode {

 *     public int val;

 *     public TreeNode left, right;

 *     public TreeNode(int val) {

 *         this.val = val;

 *         this.left = this.right = null;

 *     }

 * }

 */

public class Solution {

    /**

     * @param root: a root of binary tree

     * @return: return a integer

     */

     //思路  深度优先遍历+递归 统计出所有的的点的最高高度

      // 保存每个节点的“边数高度”:null -> -1, 叶子 -> 0

    private Map<TreeNode, Integer> heightMap = new HashMap<>();

    private int finalDiameter = 0; // 直径(边数)

    public int diameterOfBinaryTree(TreeNode root) {

        // 1) 先算出每个节点的高度(后序)

        computeHeight(root);

        // 2) 中序遍历,利用高度表更新直径

        inorderAndUpdate(root);

        return finalDiameter;

    }

    public int computeHeight(TreeNode treeNode)//该方法易错点 容易忘记返回值需要给上一级 

    {

        if(treeNode==null)

        {

            return -1;

        }

         int heightLeft=computeHeight(treeNode.left);

         int heightRight=computeHeight(treeNode.right);

        int height=Math.max(heightLeft, heightRight) + 1;

        heightMap.put(treeNode,height);

        return height;

    }

     //

    public void  inorderAndUpdate(TreeNode treeNode) {  //计算每个点的最长路径的长度 其中只需访问所有的节点 每个节点的高度上一步已经计算好

        if(treeNode==null)

        {

            return;

        }

        inorderAndUpdate(treeNode.left);

        int leftSubTreeHeight;

        if(treeNode.left==null)

        {

            leftSubTreeHeight=-1;

        }else

        {

            leftSubTreeHeight=heightMap.get(treeNode.left);

        }

        int rightSubTreeHeight;

        if(treeNode.right==null)

        {

            rightSubTreeHeight=-1;

        }else

        {

            rightSubTreeHeight=heightMap.get(treeNode.right);

        }

        int candidateDiameter = leftSubTreeHeight + rightSubTreeHeight + 2;//该节点经过根的候选直径

        if (candidateDiameter > finalDiameter) {

            finalDiameter = candidateDiameter;

        }        

    }


}

第二种方法:

即在后序遍历的同时求出其高度 并在求出高度访问当前根节点的同时计算出直径数

/**

 * Definition of TreeNode:

 * public class TreeNode {

 *     public int val;

 *     public TreeNode left, right;

 *     public TreeNode(int val) {

 *         this.val = val;

 *         this.left = this.right = null;

 *     }

 * }

 */

public class Solution {

    /**

     * @param root: a root of binary tree

     * @return: return a integer

     */

     //思路  深度优先遍历+递归 统计出所有的的点的最高高度

      // 保存每个节点的“边数高度”:null -> -1, 叶子 -> 0

   private int maximumDiameterByEdges = 0;

    public int diameterOfBinaryTree(TreeNode root) {

        // 1) 直接后序 算出每个节点的高度(后序)同时计算出直径

         maximumDiameterByEdges = 0;

         computeHeightAndUpdate(root);

         return maximumDiameterByEdges;

    }

private int computeHeightAndUpdate(TreeNode node) {

    if (node == null)

    {

        return -1;

    }  // 空=-1  叶=0

    int leftHeight  = computeHeightAndUpdate(node.left);//leftHeight rightHeight接住的返回值

    int rightHeight = computeHeightAndUpdate(node.right);

    int currentHeight = Math.max(leftHeight, rightHeight) + 1; // 先算本节点高度

    int candidateDiameter = leftHeight + rightHeight + 2;      // 再用左右高更新直径

    if (candidateDiameter > maximumDiameterByEdges) {

        maximumDiameterByEdges = candidateDiameter;

    }

    return currentHeight; // 最后把高度回传给父节点

}




}

http://www.dtcms.com/a/326156.html

相关文章:

  • VBA即用型代码手册:计算选择的单词数Count Words in Selection
  • (Arxiv-2025)Phantom-Data:迈向通用的主体一致性视频生成数据集
  • MathType关联Wps实现公式编辑【Tex语法适配】
  • 使用行为树控制机器人(一) —— 节点
  • 【C++语法】输出的设置 iomanip 与 std::ios 中的流操纵符
  • 金蝶云星辰模拟报价功能助力企业快速决策
  • CV 医学影像分类、分割、目标检测,之分类项目拆解
  • Nginx(企业高性能web服务器)
  • 需求优先级如何划分
  • AI炼丹日志-32- memvid 大模型数据库!用视频存储+语义检索实现秒级搜索
  • Pluto Pillow如何靠 “私人定制” 枕头引爆海外市场
  • 学习笔记|decorator 装饰器是什么?
  • 2025-8-11-C++ 学习 暴力枚举(2)
  • 【Linux文件操作】文件操作系统调用
  • [激光原理与应用-231]:光学 - 光学的主要分支、研究对象、应用场合与职业方向(几何光学、物理光学、量子光学、集成光学、非线性光学制造工艺、光学系统设计)
  • 左子树之和
  • 解锁AI性能密码:RAG和智能体评估指标的终极指南
  • 简单的身份验证中间件Tinyauth
  • Day43--动态规划--674. 最长连续递增序列,300. 最长递增子序列,718. 最长重复子数组
  • 算力板卡:AI时代的“算力心脏”
  • 指针和引用的区别
  • SQL中BETWEEN与IN的差异详解
  • Mybatis学习之缓存(九)
  • BM25算法记忆
  • 推荐中的在线学习
  • macos彻底删除vscode
  • Spring JDBC
  • 零基础AI编程开发微信小程序赚流量主广告实战
  • 6s081实验1
  • redis(2)-java客户端使用(IDEA基于springboot)