04.04 检查平衡性

原题目

面试题 04.04. 检查平衡性

实现一个函数,检查二叉树是否平衡。在这个问题中,平衡树的定义如下:任意一个节点,其两棵子树的高度差不超过 1。
示例 1:

给定二叉树 [3,9,20,null,null,15,7]
    3
   / \
  9  20
    /  \
   15   7
返回 true

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]
      1
     / \
    2   2
   / \
  3   3
 / \
4   4
返回 false



第一遍解法

(废话,大家可忽略)最开始打算使用BFS的思路来做,最后发现BFS只能知道每层节点的高度,如果只判断根节点左子树高度与右子树高度之差是不行的,因为可能根节点下的某个子树自身不平衡而根节点左右子树高度差小于等于1的情况。

DFS,既然直接判断大树是否平衡是不行的,可以分治,如果左树和右树都是平衡的,且高度之差小于等于1,那么就认为该树是平衡的。

class Solution {
    public boolean isBalanced(TreeNode root) {
        return isTreeBalanced(root) != -1 ? true : false;
    }

    private int isTreeBalanced(TreeNode node) {
        if (node == null) {
            return 0;
        }
        int leftHigh = isTreeBalanced(node.left);
        int rightHigh = isTreeBalanced(node.right);
        if (leftHigh == -1 || rightHigh == -1) {
            return -1;		// -1表示不平衡
        }
        if (Math.abs(leftHigh - rightHigh) > 1) {
            return -1;
        }
        return leftHigh > rightHigh ? leftHigh + 1 : rightHigh + 1;

    } 
}

时间复杂度: O(n)

  • 迭代法,1+2+…+2^log(n) --> 2n - 1

空间复杂度: O(n)

  • 递归栈,最坏的情况下为n / 2



网上的解法

也是DFS思想。

class Solution {
    private boolean balanced = true;    // 默认是平衡的
    public boolean isBalanced(TreeNode root) {
        treeDepth(root);
        return balanced;
    }

    /*
        使用DFS计算以root为根的树的高度
        DFS的优点是最多访问所有节点一次
        先判断子树的平衡性,如果子树不平衡则说明整棵树是不平衡的,提前终止遍历
    */
    public int treeDepth(TreeNode root) {
        // 空树的高度为0
        // !balanced返回0完全是为了终止递归,其实返回什么无所谓
        if (root == null || !balanced) {    
            return 0;
        }
        int leftTreeDepth = treeDepth(root.left);       // 左子树高度
        int rightTreeDepth = treeDepth(root.right);     // 右子树高度
        // 平衡性判断
        if (Math.abs(leftTreeDepth - rightTreeDepth) > 1) {
            balanced = false;
        }
        // root树的高度应该是左右子树较大者 + 1
        return Math.max(leftTreeDepth, rightTreeDepth) + 1;
    }
}

作者:zui-weng-jiu-xian
链接:https://leetcode-cn.com/problems/check-balance-lcci/solution/xin-shou-di-gui-jie-fa-by-zui-weng-jiu-xian/
来源:力扣(LeetCode)

时间复杂度: O(n)

空间复杂度: O(n)



最后的代码

结合网上代码形式,简洁了下自己代码的判断条件。但发现与网上代码基本一致了,想了好一会都不知道还应该如何简洁。

class Solution {
    private boolean balanced = true;

    public boolean isBalanced(TreeNode root) {
        treeDepth(root);
        return balanced;
    }

    private int treeDepth(TreeNode node) {
        if (node == null || !balanced) {
            return 0;
        }
        int leftHigh = treeDepth(node.left);
        int rightHigh = treeDepth(node.right);
        if (Math.abs(leftHigh - rightHigh) > 1) {
            balanced = false;
        }
        return Math.max(leftHigh, rightHigh) + 1;
    } 
}



小结

  • Math.abs求绝对值,Math.max求最大值,Math.min求最小值。

  • 遇到树的问题应当与遇到图的问题一样,先在脑海中过一遍DFS或者BFS能不能解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值