剑指 Offer 55 - II. 平衡二叉树

最容易想到的办法是先序遍历,从顶至底判断每个子树是不是平衡二叉树。

缺点是产生大量重复计算,代码如下。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) return true;
        return isBalanced(root.left) && isBalanced(root.right) && (Math.abs(depth(root.left) - depth(root.right)) <= 1);
    }

    int depth(TreeNode root){
        if(root == null)
            return 0;
        return Math.max(depth(root.left), depth(root.right)) + 1;
    }
}

K神给的最佳解法:

后序遍历 + 剪枝 (从底至顶)

觉得函数的设计很巧妙,recur函数返回的依然是深度,不用向上面加一个depth函数。

同时使用-1判断子树是否平衡,一旦出现不平衡情况直接剪枝,在isBlanced的用返回值是否为-1判断是否是平衡二叉树。

最终返回只有两种情况,一种是树的深度,另一种是-1。

相当于是在 剑指 Offer 55 - I. 二叉树的深度 进行的过程中得到了本题的解。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    //只用判断返回值是不是-1,即在子树中有没有出现过不平衡
    public boolean isBalanced(TreeNode root) {
        return recur(root) != -1;
    }


    //后序遍历加剪枝,实现从底向上返回高度
    int recur(TreeNode root){
        //当遍历越过叶结点,返回高度0
        if(root == null)
            return 0;

        //遍历左子树,左子树不平衡直接返回
        int left = recur(root.left);
        if(left == -1)
            return -1;

        //遍历右子树,右子树不平衡直接返回
        int right = recur(root.right);
        if(right == -1)
            return -1;

        //当前是平衡二叉树就返回高度
        //不是返回-1,然后由上面返回-1给isBlanced
        return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1;
    }
}

 

posted @ 2021-03-25 21:38  星予  阅读(36)  评论(0编辑  收藏  举报