[路飞]_leetcode刷题_110. 平衡二叉树

145 阅读1分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战

题目

110. 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例 1:

image.png

输入: root = [3,9,20,null,null,15,7]
输出: true

示例 2:

image.png

输入: root = [1,2,2,3,3,null,null,4,4]
输出: false

示例 3:

输入: root = []
输出: true

解法一

思路

自顶向下递归。

根据平衡二叉树的定义,我们用递归的思想去分析,一个二叉树是平衡二叉树需要满足以下几个条件

  1. 左子树和右子树都是平衡二叉树
  2. 左子树的高度和右子树的高度相差不超过1

那么这里,判断左右子树是否为平衡二叉树,可以用递归的方法去判断,但是有个问题,高度相差不超过1怎么判断呢

假设我们定义一个height方法,传入节点后可以返回以该节点为根节点的子树的高度。

那么判断左右子树高度相差不超过1的表达式就如下

Math.abs( height(root.left) - height(root.right) ) <= 1

那么问题又来了,height函数如何实现呢,以下几点为基本思想

  1. 传入的节点为空,那么返回0,即高度为0
  2. 但凡传入的节点的高度不为空,不管有没有子节点,高度至少是1
    • 那么高度就应该为左右子树里更高的一个再加上1

这里判断高度也需要再次使用递归

代码如下

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function(root) {
    if(root == null){
        return true
    }else{
        return isBalanced(root.left) && isBalanced(root.right) && Math.abs(height(root.left) - height(root.right)) <= 1
    }
};

function height(root){
    if(root == null){
        return 0
    }else{
        return Math.max(height(root.left),height(root.right)) + 1
    }
}

解法二

思路

自底向上。

解法一的自顶向下递归,会导致height函数被多次调用,造成时间复杂度过高。我们如果采用自底向上的方式递归的话,在发现有非平衡二叉树的时候,可以提前结束,直接返回false。

这跟翻转二叉树的逻辑有异曲同工之妙,采用二叉树的后序遍历。

  1. 遍历到叶子结点后,开始判断节点的左右子树是否为平衡二叉树,且返回左右子树的高度
    • 如果子树不是平衡二叉树则高度返回-1
    • 如果子树是平衡二叉树,则返回其高度,高度计算方式和解法一一样
  2. 如果左右子树有一个不是平衡二叉树,则直接返回 -1
  3. 如果左右子树高度相差大于1,也直接返回 -1
  4. 如果左右子树都是平衡二叉树,且高度相差小于等于1,那么计算当前子树的高度并返回

代码如下

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function(root) {
    return height(root)>=0;
};

function height(root){
    if(root == null){
        return 0
    }
    let leftHeight = height(root.left);
    let rightHeight = height(root.right);
    if(leftHeight == -1 || rightHeight == -1 || Math.abs(leftHeight-rightHeight)>1){
        return -1
    }else{
        return Math.max(leftHeight,rightHeight) + 1
    }
}