zoukankan      html  css  js  c++  java
  • LeetCode110. 平衡二叉树

    平衡二叉树:每一个节点的左右子树的高度差不超过1.

      对于一颗树,它是一个平衡二叉树需要满足三个条件它的左子树是平衡二叉树,它的右子树是平衡二叉树,它的左右子树的高度差不大于1。

    本题同:剑指39.平衡二叉树

      本题的递归关键是找好递归的返回值。

    ☆☆☆思路1:自顶向下的递归,类似于前序遍历。借助一个获取树深度的递归函数。

          思路1的缺点是在判断上层节点时,会多次重复遍历下层节点,增加了不必要的开销,会重复计算多次子树高度。

    ☆☆☆☆思路2【最优解】:自底向上的递归,类似于后序遍历。边求高度边判断,对于每个节点,高度height只会被调用一次。

    ☆☆☆☆思路3:新定义一个内部类,使得递归的返回值包括 当前树是否是BST当前树的高度 这两个信息

    class Solution {
        // 返回值应该包含当前树是否是BST和当前树的高度这两个信息
        private class ReturnNode{
            boolean isB;
            int depth;
            public ReturnNode(int depth, boolean isB) {
                this.depth = depth;
                this.isB = isB;
            }
        }
        public boolean isBalanced(TreeNode root) {
            /**
             * 方法1:自顶向下递归,类似于前序遍历
             *      时间复杂度:O(n^2)
             */
            /*
            if (root == null) return true;
            // Step1:对于当前遍历的节点进行判断
            int l = treeDepth(root.left);
            int r = treeDepth(root.right);
            if (Math.abs(l - r) > 1) return false;
            // Step2:递归判断其左右子树是否平衡
            return isBalanced(root.left) && isBalanced(root.right);
            */
            /**
             * 方法2:自底向上,类似于后序遍历
             *       时间复杂度O(n)
             */
            return getDepth(root) != -1;
            /**
             * 方法3:
             *     参考博客:https://lyl0724.github.io/2020/01/25/1/
             */
    //        return isBST(root).isB;
        }
        // 方法1,以下函数用来获取树的最大深度
        private int treeDepth(TreeNode root) {
            if (root == null) return 0;
            return Math.max(treeDepth(root.left), treeDepth(root.right)) + 1;
        }
    
        // 方法2 自底向上,类似于后序遍历
        private int getDepth(TreeNode root) {
            if (root == null) return 0;
            // Step1:先递归判断左右子树是否平衡
            int left = getDepth(root.left);
            if (left == -1) return -1;
            int right = getDepth(root.right);
            if (right == -1) return -1;
            // Step2:再判断以当前节点为根的子树是否平衡
            return Math.abs(left-right) > 1 ? -1 : Math.max(left, right) + 1;
        }
    
        // 方法3
        private ReturnNode isBST(TreeNode root) {
            if (root == null)
                return new ReturnNode(0,true);
            //不平衡的情况有3种:左树不平衡、右树不平衡、左树和右树差的绝对值大于1
            ReturnNode left = isBST(root.left);
            ReturnNode right = isBST(root.right);
            if (left.isB == false || right.isB == false) {
                return new ReturnNode(0,false);
            }
            if (Math.abs(left.depth - right.depth) > 1) {
                return new ReturnNode(0,false);
            }
            //不满足上面3种情况,说明平衡了,树的深度为左右俩子树最大深度+1
            return new ReturnNode(Math.max(left.depth,right.depth) + 1, true);
        }
    }
    
    
  • 相关阅读:
    编译原理基础知识---文法和语言(一)
    编译原理简单知识总结(一)---编译程序和解释程序
    python网络编程
    博客声明
    v4l2编程
    Linux中的虚拟文件系统
    linux 内核文件中Makefile、kconfig、.config的关系(SDK结构)
    shell编程---find命令
    springcloud、springboot 版本号解析
    List<Map<String, Object>> 与 json 互转
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/14171741.html
Copyright © 2011-2022 走看看