求二叉树节点的最大距离、最大直径(最简单的解法+常规解法)

算法 专栏收录该内容
88 篇文章 0 订阅

求二叉树节点的最大距离(最大直径)


题目:写一个程序求一棵二叉树中相距最远的两个节点之间的距离。

力扣:543. 二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

第一种实现方法(常规)

计算一个二叉树的最大距离有两个情况:

  1. 路径经过根节点:路径经过左子树的最深节点,通过根节点,再到右子树的最深节点。
  2. 路径不经过根节点:而是左子树或右子树的最大距离路径,取其大者。

所以,需要计算这两个情况的路径距离,并取其大者,就是该二叉树的最大距离。

    class Node {
        public Node left; //左子树
        public Node right; //右子树
        public int lMax; //左子树的最大距离
        public int rMax; //右子树的最大距离
        public int val; //节点的值
    }

    int maxPath = 0;

    /**
     * 求二叉树中节点的最大距离
     * @param root
     */
    public void findMaxPath(Node root){
        if (root == null){
            return;
        }
        // 如果左子树为空,那么该节点的左边最长距离为0
        if (root.left == null){
            root.lMax = 0;
        }
        if (root.right == null){
            root.rMax = 0;
        }
        // 如果左子树不为空,递归寻找左子树最长距离
        if (root.left != null){
            findMaxPath(root.left);
        }
        if (root.right != null){
            findMaxPath(root.right);
        }
        // 计算左子树最长节点距离
        if (root.left != null){
            int len = 0;
            if (root.left.lMax > root.left.rMax){
                len = root.left.lMax;
            }else{
                len = root.left.rMax;
            }
            root.lMax = len + 1;
        }
        if (root.right != null){
            int len = 0;
            if (root.right.lMax > root.left.rMax){
                len = root.right.lMax;
            }else{
                len = root.right.rMax;
            }
            root.rMax = len + 1;
        }
        // 更新最长距离
        if (root.lMax + root.rMax > maxPath){
            maxPath = root.lMax + root.rMax;
        }
    }

第二种实现方法(简单解法)

第一种方案比较复杂,代码也比较多。

我们可以换一种思路:此题中,最终是求2个节点间的路径。虽然这个路径可能不经过根节点,但是,必然会以一个节点为根(根节点或子树根节点),2个目标节点分布在这个根节点的左子树和右子树中。所以,等同于“计算每个节点的左子树和右子树的高度和,然后取最大值”。

可以将二叉树的直径转换为:二叉树的每个节点的左右子树的高度和的最大值。

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
    
    
    int maxPath = 0;
      /**
     * 求二叉树中节点的最大距离
     * @param root
     */
    public int diameterOfBinaryTree(TreeNode root) {
        depth(root);
        return maxPath;
    }
    public int depth(TreeNode root){
        if(root == null){
            return 0;
        }
        int left = depth(root.left);
        int right = depth(root.right);
        
        if(left + right> maxPath){
            maxPath = left + right;
        }
        return Math.max(left, right) + 1;
    }


  • 1
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值