博主信息
Sky
博文
291
粉丝
0
评论
0
访问量
7204
积分:0
P豆:617

平衡二叉树

2021年10月18日 20:43:39阅读数:13博客 / Sky

题目描述

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

基本知识点

二叉树的每个节点最多有两个子节点,平衡二叉树中任意一个节点的左右子树高度相差不能大于 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}
*/
const isBalanced = function (root) {
 if (root === null) {
   return true;
 } else {
   return (
     Math.abs(height(root.left) - height(root.right)) <= 1 &&
     isBalanced(root.left) &&
     isBalanced(root.right)
   );
 }
};

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

时间复杂度分析

该方法最坏的情况是每个父节点都只有一个子节点,这样树的高度时间复杂度为 O(n),即“链表”的长度。而第 d 层调用 height 函数的时间复杂度是 O(d),所以整体的时间复杂度为高度时间复杂度 * 调用 height 函数的时间复杂度,即 O(n^2)。

空间复杂度分析

该方法由于使用了递归,并且每次递归都调用了两次自身,导致会函数栈会按照等差数列开辟,所以该方法的空间复杂度应为 O(n^2)。

解法二

思路

上面的方法是自顶而上的,这样其实就会导致每层的高度都要重复计算。那么,我们可以使用后序遍历手机游戏账号转让,这样每个节点的高度就能根据前面的结果算出来。

代码

/**
* 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) != -1;
};

var height = function (root) {
 if (root == null) {
   return 0;
 }

 const left = height(root.left);
 const right = height(root.right);

 if (left === -1 || right === -1 || Math.abs(left - right) > 1) {
   return -1;
 }

 return Math.max(left, right) + 1;
};

时间复杂度分析

由于是后序遍历,每个节点只会被调用 1 次,所以,该方法的时间复杂度是 O(n)。

空间复杂度分析

该方法由于使用了递归,并且每次递归都调用了两次自身,导致会函数栈会按照等差数列开辟,所以该方法的空间复杂度应为 O(n^2)。

版权申明:本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!

全部评论

文明上网理性发言,请遵守新闻评论服务协议

条评论
  • 排序并没有直接的关系,但是排序的查找效率与的形态有关,所有当我们希望排序的形态是均匀的时候,这样的就被称为
    中,有一种叫做。今天我们就来介绍一下判断该是不是的方法,有需要的小伙伴可以参考一下。
    是基于分法的策略提高数据的查找速度的的数据结构。采用分法思维把数据按规则组装成一个形结构的数据,用这个形结构的数据减少无关数据的检索,大大的提升了数据检索的速度。
    可用于实现查找堆,在计算机科学中,是每个结点最多有两个子结构,通常子被称作“左子”和“右子”,根据不同的用途可分为:1、完全;2、满;3、
    的特点有:1、非叶子节点最多拥有两个子节点;2、非叶子节值大于左边子节点、小于右边子节点;3、的左右两边的层级数相差不会大于1;4、没有值相等重复的节点。
    有八种不同的形态,分别是:1、空;2、只有根节点的;3、只有根节点和左子TL的;4、只有根节点和右子TR的;5、具有根节点,左子TL和右子TR的;6、斜
    有五种基本形态,分别是:1、空;2、只有一个根结点的;3、只有左子;4、只有右子;5、完全
    搜索排序是一样的,英文全称是“Binary Search Tree”,搜索作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势。
    搜索又称查找排序,一棵搜索是以来组织的,可以使用一个链表数据结构来表示,其中每一个结点就是一个对象;一般地,除了key和卫星数据之外,每个结点还包含属性lchild、rchild
    有两种实现方式,分别是:1、顺序存储,指的是使用顺序表存储,只适用于完全;2、链式存储,用链接方式存储时,每个结点除了存储结点本身的数据外,还应设置两个指针域lchild和rchild
    在上篇文章中,我们学习了的基本链式结构以及建和遍历相关的操作。今天我们学习的则是一些相关的概念以及的一种变形形式。
    搜索的特点是对于中的每个节点X,它的左子中所有关键字值小于X的关键字值,而它的右子中所有关键字值大于X的关键字值;根据这个性质,对一个进行中序遍历,如果是单调递增的,则可以说明这个搜索
    搜索主要用于搜索和动态排序,进行“插入/查询/删除”的时间复杂度为“O(log(n))”,但是实际使用的时候通常不会有这么快,因为插入顺序所用的“middle”通常不是那么准。
    在计算机科学中,(英语:Binary tree)是每个节点最多只有两个分支(即不存在分支度大于2的节点)的结构。通常分支被称作“左子”或“右子”。的分支具有左右次序,不能随意颠倒。
    一个某结点的坡度就是该结点左子的结点之和和右子结点之和的差的绝对值。今天我们就来聊聊计算坡度的方法,有需要的可以参考参考。
    在计算机领域,我们天天要打交道的【文件夹】、数据库中我们存储的数据,都是的典型的应用。今天我们来学习的就是比较偏理论的关于的定义以及它们的一些属性特点。
    由三个结点可以构造出5种不同的是n个有限元素的集合,该集合或者为空、或者由一个称为根的元素及两个不相交的,被分别称为左子和右子组成,是有序
    首先,我们还是要说明一下,我们学习的主要内容是,因为是最典型的一种的应用,不管是考试还是面试,它都是必知必学的内容。
    给定一个搜索, 找到该中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根T的两个结点p、q,最近公共祖先表示为一个结点x,满足x是p、q的祖先且x的深度尽可能大。”
    C语言中中序遍历的方法:首先遍历左子,并借助递归继续访问直到最左侧节点;然后访问根结点;最后遍历右子,并借助递归继续访问直到最右侧节点即可。