js算法题解(第二十五天)---110. 平衡二叉树

227 阅读3分钟

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

前言

每天至少一道算法题,死磕算法

我们为什么需要平衡二叉树?

平衡二叉树是特殊的二叉树,面试中考二叉树,就经常考特殊的二叉树,因为特殊的二叉树用处才大,我们先来看一下二叉平衡术的用途

图一

图片.png

这棵就是平衡二叉树

图二

图片.png

这棵就不是

如果我们要查询val为1的话,图一需要几步?3步妥妥的

图二呢,数了半天,需要5步

所以平衡二叉树能够缩短我们的查询时间

接下来我们复习一下二叉平衡树的定义。

平衡二叉树是任意结点的左右子树高度差绝对值都不大于1的二叉搜索树。

抓住其中的三个关键字:

  • 任意结点
  • 左右子树高度差绝对值都不大于1
  • 二叉搜索树

发现这些关键字都是我们熟悉的东西,那么题目应该也不太难做

题目

这是leetcode上的第110道题目110. 平衡二叉树

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

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

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

图片.png

示例 1:

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

思路

  • 第一步从题目中提取关键字

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 这句话怎么这么熟悉,这不就是昨天我们写的那个生成二叉搜索树那到题目么,他其实就是一个高度平衡二叉树

只要有关联,那么今天这道题目肯定就好写了

需要注意的是,我们这里的二叉平衡树和真正的二叉平衡树的定义是不一样的,屏幕中给出的定义是一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。没有说是二叉搜索树,所以我们没有必要验证是不是二叉搜索树,ღ( ´・ᴗ・` )比心

  • 第二点分析

我们要判断左右两个子树的高度差的绝对值不超过 1 。其实就是判断每个节点的左右子树的高度的绝对值的差值大不大于1,所以我们就递归求高度好了,我们以前学层序遍历的时候,学过求高度的方法,但是层数遍历复杂度太高了,直接O(n^2)了,所以今天我们在教一个逆向思维求高度的方法,也被称为自底向上求递归

function getHeight(root){
    // 如果不存在高度为0
    if(!root){
        return 0;
    }
    const left = getHeight(root.left);
    const right = getHeight(root.right);
    return Math.max(left,right)+1;
}

有了这个方法,我们在加一下flag和判断高度绝对值的方法就结束了

题解

var isBalanced = function(root) {
    let flag = true;
    const getHeight = function(root){
        // root为null,或者flag=false,那么就不用执行了,直接返回高度0
        if(!root||!flag){
            return 0;
        }
        let left = getHeight(root.left);
        let right = getHeight(root.right);
        if(Math.abs(left-right)>1){
            flag = false;
        }
        // 逆想思维求高度
        return Math.max(left,right)+1;
    }
    getHeight(root);
    return flag;
};
  • 时间复杂度:O(n),其中n为二叉树的节点个数。因为每个节点都会处理一次
  • 空间复杂度:O(n),空间复杂度主要取决于递归调用的层数,如果是一个一直只有左节点的树,那么空间复杂度最大为n

参考