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

99 阅读2分钟

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

难度简单216

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过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

限制:

  • 0 <= 树的结点个数 <= 10000

注意:本题与主站 110 题相同:leetcode-cn.com/problems/ba…

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

/**
 * 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) {
         return height(root) >= 0;
    }
​
    public int height(TreeNode root){
        if(root == null) return 0;
        int leftH = height(root.left);
        int rightH = height(root.right);
        if(leftH== -1||rightH == -1 || Math.abs(leftH-rightH)>1){
            return -1; //通过abs(leftH-rightH)条件直接判断子树是否balanced,如果不是-1则剪枝
        }else{
            return Math.max(height(root.left),height(root.right)) + 1;  // 递归到某个子树的叶子节点,然后算出这棵子树的深度
        }
​
    }
}
​
//后序遍历,自底向上,可以在回溯时直接判断子树是否balance,如果不是则不符题意,直接剪枝。
​
​

先序遍历 + 判断深度(从顶至底)- 我觉得还是后序遍历

class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) return true;
        return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }
​
    private int depth(TreeNode root) {
        if (root == null) return 0;
        return Math.max(depth(root.left), depth(root.right)) + 1;
    }
}
​
注释:对我来说这样写其实并不好理解
主要是isBalanced(root.left) 和 isBalanced(root.right),其实是依赖于 Math.abs(depth(root.left) - depth(root.right)) ,然后三者又写在同一级的return里,让人很困惑。
​
并且我用leetcode 来追踪这道题,return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);并不按顺序执行,而先执行isBalanced(root.left) 
​
​
这道题的解题思路,还是用后序遍Math.max(depth(root.left), depth(root.right)) + 1;
​
​
表达式解惑:
Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
​
之所有用这个条件,是因为有可能左右子树最终的叶子节点深度可能一样,但子树则未必满足balance tree条件,所以还是要isBalanced(root.left) && isBalanced(root.right)这两个条件.例如下面这棵树
​
              1
             /  \
            2    2
           /      \
          3        3
         /          \
        4           4
         
​
作者:jyd
链接:https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/solution/mian-shi-ti-55-ii-ping-heng-er-cha-shu-cong-di-zhi/
​
​
另一版答案
class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        if (Math.abs(depth(root.left) - depth(root.right)) <= 1) {
            return isBalanced(root.left) && isBalanced(root.right);
        }else {
            return false;
        }
    }
​
    private int depth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left != null && root.right != null) {
            return Math.max(depth(root.left), depth(root.right)) + 1;
        } else if (root.left != null) {
            return depth(root.left) + 1;
        } else {
            return depth(root.right) + 1;
        }
    }
}
​

\