【二叉树】55题-平衡二叉树

1 题目描述

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

限制:

1 <= 树的结点个数 <= 10000

2 解题思路

2.1 方法1:后序遍历+剪枝(从底至顶)(最优解法)

思路是对二叉树做后序遍历,从底至顶返回子树深度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。

算法流程:
recur(root)函数:

  • 返回值:
    • 当节点root左/右子树的深度差小于等于1:则返回当前子树的深度,即节点root的左/右子树的深度最大值+1(max(left,right)+1);
    • 当节点root左/右子树的深度差大于2;则返回-1,代表此子树不是平衡树。
  • 终止条件:
    • 当root为空:说明越过叶节点,因此返回高度0;
    • 当左(右)子树深度-1:代表此树的左(右)子树不是平衡树,因此剪枝,直接返回-1;

isBalanced(root)函数:

  • 返回值:若recur(root)!=-1,则说明此树平衡,返回true;否则返回false。
/**
 * 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 recur(root) == -1 ? false : true;
    }
    private int recur(TreeNode node) {
        if (node == null) return 0;
        int left = recur(node.left);
        if (left == -1) return -1;
        int right = recur(node.right);
        if (right == -1) return -1;
        return Math.abs(left - right) < 2 ? Math.max(left,right) + 1 : -1;
    }
}

复杂度分析:

  • 时间复杂度O(N):N为树的节点数;最差情况下,需要递归遍历树的所有节点。
  • 空间复杂度O(N):最差情况下(树退化为链表时),系统递归需要使用O(N)的栈空间。

2.2 方法2:先序遍历 + 判断深度 (从顶至底)

思路是构造一个获取当前子树的深度的函数depth(root),通过比较某子树的左右子树的深度差abs(depth(root.left)-depth(root.right)) <= 1是否成立,来判断某子树是否是二叉平衡树。若所有子树都是平衡,则此树平衡。

算法流程:
isBalanced(root)函数:判断树root是否平衡

  • 特例处理:若树根节点root为空,则直接返回true;
  • 返回值:所有子树都需要满足平衡树性质,因此以下三者使用与逻辑&&连接;
    • abs(depth(root.left)-depth(root.right))<=1:判断当前子树是否为平衡树;
    • isBalanced(root.left):先序遍历递归,判断当前子树的左子树是否平衡树;
    • isBalanced(root.right):先序遍历递归,判断当前子树的右子树是否为平衡树;
      wei
      depth(root)函数:计算树root的深度。
  • 终止条件:当root为空,即越过叶子节点,则返回高度0;
  • 返回值:返回左/右子树的深度的最大值+1。
/**
 * 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 Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }
    private int depth(TreeNode node) {
        if (node == null) return 0;
        return Math.max(depth(node.left),depth(node.right)) + 1;
    }
}

复杂度分析:
时间复杂度O(NlogN):最差情况下(为“满二叉树”时),isBalanced(root)遍历树所有节点,判断每个节点的深度depth(root)需要遍历各子树的所有节点。

  • 空间复杂度O(N):最差情况下(树退化为链表时),系统递归需要使用O(N)的栈空间。
相关推荐

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值