leetcode110.平衡二叉树

1.题目描述:

给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。

2.自顶向下递归:

判断当前节点左右两子树的高度差绝对值是否超过1,也就是判断当前节点是否平衡,随后递归判断各个节点是否平衡。左右子树的高度差计算由leetcode104. 二叉树的最大深度给出。递归三步骤,①递归终止条件:root = null,返回true。②每级递归需要做什么:判断当前节点是否平衡。③返回值:若当前节点不平衡返回false,若当前节点平衡递归返回当前节点的左右节点是否平衡。代码如下:

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

    public int height(TreeNode curNode) {
        return curNode == null ? 0 : Math.max(height(curNode.left),height(curNode.right)) + 1;
    }
}

将递归的二、三步合并:

return Math.abs(height(root.left) - height(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);

复杂度分析:

在判断当前节点是否平衡时,会调用当前节点子节点的height方法,而height会递归走遍其下所有节点,也就是说当前节点的深度若为n,它会被他之前所有的父节点调用即共被调用n次。大部分的节点height被重复调用。以满二叉树为例,时间复杂度近似为nlog2n,最坏情况二叉树为链表时,一共遍历n * (n - 1) / 2次,时间复杂度为O(n^2)。空间复杂度由于一次递归层级最大为n,所以为O(n),这里没有算入height递归的空间复杂度,有待商榷。

3.自底向上递归:

在递归计算节点height高度的过程中,直接判断其下节点中是否出现不平衡节点,若出现不平衡节点则直接返回false及时止损,但程序还是完整遍历所有节点,也就是只需要调用root节点的height方法即可遍历所有节点,自底向上判断所有节点是否平衡。时间复杂度和空间复杂度容易判断,均为O(n)。方法的写法有多种,举两个如下:

class Solution {
    boolean flag = true;
    public boolean isBalanced(TreeNode root) {
        depth(root);
        return flag;
    }
    public int depth(TreeNode curNode){
        if(curNode == null) return 0;
        int l = depth(curNode.left);
        int r = depth(curNode.right);
        if(Math.abs(l - r) > 1) flag = false;
        return Math.max(l,r) + 1;
    }
}
class Solution {
    public boolean isBalanced(TreeNode root) {
        return height(root) >= 0;
    }

    public int height(TreeNode root) {
        if (root == null) return 0;
        int l = height(root.left);
        int r = height(root.right);
        if (l == -1 || r == -1 || Math.abs(l - r) > 1) return -1;
        else return Math.max(l,r) + 1;
    }
}

4.二刷递归:

class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) return true;
        if (Math.abs(depth(root.left) - depth(root.right)) > 1) return false;
        return isBalanced(root.left) && isBalanced(root.right);
    }

    public int depth(TreeNode root) {//借助深度差来判断
        if (root == null) return 0;
        return 1 + Math.max(depth(root.left), depth(root.right));
    }
}

自底向上:在求深度的同时直接加入平衡二叉树的定义判断。

class Solution {
    boolean flag = true;
    public boolean isBalanced(TreeNode root) {
        depth(root);
        return flag;
    }
    public int depth(TreeNode root) {
        if (root == null) return 0;
        int left = depth(root.left);
        int right = depth(root.right);
        if (Math.abs(left - right) > 1) {
            flag = false;
            return 0;//直接返回,不走完深度的全程判断
        }
        return Math.max(left, right) + 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值