-
2020-05-18 09:56:40
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 。
class Solution { public boolean isBalanced(TreeNode root) { return recur(root) != -1; } private int recur(TreeNode root) { if (root == null) return 0; int left = recur(root.left); if(left == -1) return -1; int right = recur(root.right); if(right == -1) return -1; return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1; } }
class Solution { private: // Recursively obtain the height of a tree. An empty tree has -1 height int height(TreeNode* root) { // An empty tree has height -1 if (root == NULL) { return -1; } return 1 + max(height(root->left), height(root->right)); } public: bool isBalanced(TreeNode* root) { // An empty tree satisfies the definition of a balanced tree if (root == NULL) { return true; } // Check if subtrees have height within 1. If they do, check if the // subtrees are balanced return abs(height(root->left) - height(root->right)) < 2 && isBalanced(root->left) && isBalanced(root->right); } };
更多相关内容 -
二叉树算法题(7)平衡二叉树
2021-10-28 21:19:03本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 示例 1 输入:root = [3,9,20,null,null,15,7] 输出:true 示例 2 输入:root = [1,2,2,3,3,null,...目录
平衡二叉树
描述
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1
示例 1
输入:root = [3,9,20,null,null,15,7] 输出:true
示例 2
输入:root = [1,2,2,3,3,null,null,4,4] 输出:false
示例 3
输入:root = [] 输出:true
提示
- 树中的节点数在范围 [0, 5000] 内
方法:递归
本题我们可以从底向上求,先递归到叶子节点,计算包含叶子结点的子树是否平衡,如果不平衡则返回-1,如果平衡则返回当前子树的深度,对每个节点进行左右子树深度差不大于1的判断,只要不平衡就返回-1,最后到根节点只用判断根节点的深度是否为-1就知道是否平衡了。
class Solution { public boolean isBalanced(TreeNode root) { return calDepth(root)!=-1; } public int calDepth(TreeNode root){ if (root==null) return 0; int leftDepth=calDepth(root.left);//递归计算左子树深度 int rightDepth=calDepth(root.right);//递归计算右子树深度 if (leftDepth==-1||rightDepth==-1||Math.abs(leftDepth-rightDepth)>1) return -1;//如果当前子树不平衡,那么直接返回-1 else return Math.max(leftDepth,rightDepth)+1;//如果是平衡的返回当前子树的深度 } }
-
平衡二叉树专题
2021-02-12 02:06:04今天给大家精选了 4 道题,如果你彻底搞明白了这几道题,碰到其他的平衡二叉树的题目应该不至于没有思路。当你领会了我的思路之后, 建议再找几个题目练手,巩固一下学习成果。110. 平衡二叉树(简单)最简单的莫过于...力扣关于平衡二叉树的题目还是有一些的,并且都非常经典,推荐大家练习。今天给大家精选了 4 道题,如果你彻底搞明白了这几道题,碰到其他的平衡二叉树的题目应该不至于没有思路。当你领会了我的思路之后, 建议再找几个题目练手,巩固一下学习成果。
110. 平衡二叉树(简单)
最简单的莫过于判断一个树是否为平衡二叉树了,我们来看下。
题目描述
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过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。用伪代码描述就是:
if abs(高度(root.left) - 高度(root.right)) <= 1 and root.left 也是平衡二叉树 and root.right 也是平衡二叉树:
print('是平衡二叉树')
else:
print('不是平衡二叉树')
而 root.left 和 root.right 如何判断是否是二叉平衡树就和 root 是一样的了,可以看出这个问题有明显的递归性。
因此我们首先需要知道如何计算一个子树的高度。这个可以通过递归的方式轻松地计算出来。计算子树高度的 Python 代码如下:
def dfs(node, depth):
if not node: return 0
l = dfs(node.left, depth + 1)
r = dfs(node.right, depth + 1)
return max(l, r) + 1
代码
代码支持: Python3
Python3 Code:
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def dfs(node, depth):
if not node: return 0
l = dfs(node.left, depth + 1)
r = dfs(node.right, depth + 1)
return max(l, r) + 1
if not root: return True
if abs(dfs(root.left, 0) - dfs(root.right, 0)) > 1: return False
return self.isBalanced(root.left) and self.isBalanced(root.right)
复杂度分析
时间复杂度:对于 isBalanced 来说,由于每个节点最多被访问一次,这部分的时间复杂度为 $O(N)$,而 dfs 函数 每次被调用的次数不超过 $log N$,因此总的时间复杂度为 $O(NlogN)$,其中 $N$ 为 树的节点总数。
空间复杂度:由于使用了递归,这里的空间复杂度的瓶颈在栈空间,因此空间复杂度为 $O(h)$,其中 $h$ 为树的高度。
108. 将有序数组转换为二叉搜索树(简单)
108 和 109 基本是一样的,只不过数据结构不一样,109 变成了链表了而已。由于链表操作比数组需要考虑更多的因素,因此 109 是 中等难度。
题目描述
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
思路
对于这个问题或者 给定一个二叉搜索树,将其改为平衡(后面会讲) 基本思路都是一样的。
题目的要求是将有序数组转化为:
高度平衡的二叉树
二叉搜索树
由于平衡二叉树是左右两个子树的高度差的绝对值不超过 1。因此一种简单的方法是选择中点作为根节点,根节点左侧的作为左子树,右侧的作为右子树即可。原因很简单,这样分配可以保证左右子树的节点数目差不超过 1。因此高度差自然也不会超过 1 了。
上面的操作同时也满足了二叉搜索树,原因就是题目给的数组是有序的。
你也可以选择别的数作为根节点,而不是中点,这也可以看出答案是不唯一的。
代码
代码支持: Python3
Python3 Code:
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if not nums: return None
mid = (len(nums) - 1) // 2
root = TreeNode(nums[mid])
root.left = self.sortedArrayToBST(nums[:mid])
root.right = self.sortedArrayToBST(nums[mid + 1:])
return root
复杂度分析
时间复杂度:由于每个节点最多被访问一次,因此总的时间复杂度为 $O(N)$,其中 $N$ 为数组长度。
空间复杂度:由于使用了递归,这里的空间复杂度的瓶颈在栈空间,因此空间复杂度为 $O(h)$,其中 $h$ 为树的高度。同时由于是平衡二叉树,因此 $h$ 就是 $log N$。
109. 有序链表转换二叉搜索树(中等)
题目描述
`给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
思路
和 108 思路一样。 不同的是数据结构的不同,因此我们需要关注的是链表和数组的操作差异。
(数组的情况)
我们再来看下链表:
(链表的情况)
找到中点,只需要使用经典的快慢指针即可。同时为了防止环的出现, 我们需要斩断指向 mid 的 next 指针,因此需要记录一下中点前的一个节点,这只需要用一个变量 pre 记录即可。
代码
代码支持: Python3
Python3 Code:
class Solution:
def sortedListToBST(self, head: ListNode) -> TreeNode:
if not head:
return head
pre, slow, fast = None, head, head
while fast and fast.next:
fast = fast.next.next
pre = slow
slow = slow.next
if pre:
pre.next = None
node = TreeNode(slow.val)
if slow == fast:
return node
node.left = self.sortedListToBST(head)
node.right = self.sortedListToBST(slow.next)
return node
复杂度分析
时间复杂度:由于每个节点最多被访问一次,因此总的时间复杂度为 $O(N)$,其中 $N$ 为链表长度。
空间复杂度:由于使用了递归,这里的空间复杂度的瓶颈在栈空间,因此空间复杂度为 $O(h)$,其中 $h$ 为树的高度。同时由于是平衡二叉树,因此 $h$ 就是 $log N$。
1382. 将二叉搜索树变平衡(中等)
题目描述
给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。
如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的 。
如果有多种构造方法,请你返回任意一种。
示例:
输入:root = [1,null,2,null,3,null,4,null,null]
输出:[2,1,3,null,null,null,4]
解释:这不是唯一的正确答案,[3,1,4,null,2,null,null] 也是一个可行的构造方案。
提示:
树节点的数目在 1 到 10^4 之间。
树节点的值互不相同,且在 1 到 10^5 之间。
思路
由于二叉搜索树的中序遍历是一个有序数组,因此问题很容易就转化为 108. 将有序数组转换为二叉搜索树(简单)。
代码
代码支持: Python3
Python3 Code:
class Solution:
def inorder(self, node):
if not node: return []
return self.inorder(node.left) + [node.val] + self.inorder(node.right)
def balanceBST(self, root: TreeNode) -> TreeNode:
nums = self.inorder(root)
def dfs(start, end):
if start == end: return TreeNode(nums[start])
if start > end: return None
mid = (start + end) // 2
root = TreeNode(nums[mid])
root.left = dfs(start, mid - 1)
root.right = dfs(mid + 1, end)
return root
return dfs(0, len(nums) - 1)
复杂度分析
时间复杂度:由于每个节点最多被访问一次,因此总的时间复杂度为 $O(N)$,其中 $N$ 为链表长度。
空间复杂度:虽然使用了递归,但是瓶颈不在栈空间,而是开辟的长度为 $N$ 的 nums 数组,因此空间复杂度为 $O(N)$,其中 $N$ 为树的节点总数。
总结
本文通过四道关于二叉平衡树的题帮助大家识别此类型题目背后的思维逻辑,我们来总结一下学到的知识。
平衡二叉树指的是:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。
如果需要让你判断一个树是否是平衡二叉树,只需要死扣定义,然后用递归即可轻松解决。
如果需要你将一个数组或者链表(逻辑上都是线性的数据结构)转化为平衡二叉树,只需要随便选一个节点,并分配一半到左子树,另一半到右子树即可。
同时,如果要求你转化为平衡二叉搜索树,则可以选择排序数组(或链表)的中点,左边的元素为左子树, 右边的元素为右子树即可。
小提示 1: 如果不需要是二叉搜索树则不需要排序,否则需要排序。
小提示 2: 你也可以不选择中点, 算法需要相应调整,感兴趣的同学可以试试。
小提示 3: 链表的操作需要特别注意环的存在。
-
平衡二叉树调整--LL-LR-RL-RR
2018-07-25 13:37:21平衡二叉树调整 平衡二叉树简称平衡树,是由Adelson-Velskii和Landis于1962年首先提出的,所以又称为AVL树。他的定义很简单,就是若一棵二叉树的每个左右节点的高度差最多相差1,此二叉树即是平衡二叉树。把二叉树...平衡二叉树调整
平衡二叉树简称平衡树,是由Adelson-Velskii和Landis于1962年首先提出的,所以又称为AVL树。他的定义很简单,就是若一棵二叉树的每个左右节点的高度差最多相差1,此二叉树即是平衡二叉树。把二叉树的每个节点的左子树减去右子树定义为该节点的平衡因子。二叉平衡树的平衡因子只能是1、0或者-1。
平衡二叉树是对二叉搜索树(又称为二叉排序树)的一种改进。二叉搜索树有一个缺点就是,树的结构是无法预料的,随意性很大,它只与节点的值和插入的顺序有关系,往往得到的是一个不平衡的二叉树。在最坏的情况下,可能得到的是一个单支二叉树,其高度和节点数相同,相当于一个单链表,对其正常的时间复杂度有O(lb n)变成了O(n),从而丧失了二叉排序树的一些应该有的优点。
当插入一个新的节点的时候,在普通的二叉树中不用考虑树的平衡因子,只要将大于根节点的值插入到右子树,小于节点的值插入到左子树,递归即可。而在平衡二叉树则不一样,在插入节点的时候,如果插入节点之后有一个节点的平衡因子要大于2或者小于-2的时候,他需要对其进行调整,现在只考虑插入到节点的左子树部分(右子树与此相同)。主要分为以下三种情况:
(1)若插入前一部分节点的左子树高度和右子树高度相等,即平衡因子为0,插入后平衡因子变为1,仍符合平衡的条件不用调整。
(2)若插入前左子树高度小于右子树高度,即平衡因子为-1,则插入后将使平衡因子变为0,平衡性反倒得到调整,所以不必调整。
(3)若插入前左子树的高度大于右子树高度,即平衡因子为1,则插入左子树之后会使得平衡因子变为2,这样的情况下就破坏了平衡二叉树的结构,所以必须对其进行调整,使其加以改善。
调整二叉树首先要明白一个定义,即最小不平衡子树。最小不平衡子树是指以离插入节点最近、且平衡因子绝对值大于1的节点做根的子树。
下面讲解平衡二叉树最基本的4种调整操作,调整的原则是调整后他的搜索二叉树的性质不变,即树的中序遍历是不会改变的:
1. LL型调整。在B点的左子树上插入一个节点。插入后B点的左子树的平衡因子变为1,A节点的平衡因子变为了2。这样可以看出来A节点为根节点的子树是最小不平衡子树。调整时,将A的左孩子B向右旋转代替A称为原来不平衡子树的根节点,将A的节点右下旋转称为B的右子树的根节点,而B的原右子树变为A的左子树。详细过程如下图:
2. RR型调整操作
在A节点的右孩子的右子树上插入节点,使得A节点的平衡因子由-1变为-2而引起的不平衡所进行的调整操作。调整操作大致一样,看图就可以明白了。
3. LR型的调整操作。在A节点的左孩子的右子树上插入节点,使得A节点的平衡因子由1变为了2而引起的不平衡所进行的调整的操作。调整过程如图:
解释:LR型先向左转再向右旋转。B先变为C的左子树,CL变为B的右子树;然后右旋的含义为A变成C的右子树,CR变为A的左子树。
4. RL型的调整操作。不多说了,直接上图:
在二叉搜索树的插入和删除运算中,采用平衡树的优点是:使树的结构较好,从而提高查找运算的速度。缺点是:是插入和删除运算变得复杂化,从而降低了他们的运算速度。对二叉搜索树删除节点而引起的不平衡性进行的操作比插入节点的情况要复杂,在此就不再论述了。
-
平衡二叉树之平衡调整图解
2019-02-22 22:46:47先看一个平衡二叉树创建的例子。假设现在表中关键字序列为(13,24,37),具体的平衡二叉树创建过程如下图所示: 我们可以发现结点37的插入导致二叉树的根结点13的平衡因子变为-2,此时二叉树没有达到平衡状态。... -
考研之数据结构018_平衡二叉树(AVL)
2021-05-11 14:34:52考研之数据结构016_平衡二叉树AVL一、定义二、插入操作三、插入后调整“不平衡”问题1.LL左孩子左子树平衡旋转(右单旋转)1.LL代码:2.RR右孩子右子树平衡旋转(左单旋转)1.RR代码:3.LR左孩子右子树平衡旋转( ... -
二叉树、平衡二叉树、红黑树、B/B+树总结及相关面试题
2021-03-05 18:03:05一、二叉树 二叉树是每个结点最多有两个子树的有序树,子树的根被称作左子树和右子树。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。叶节点,分支节点,根节点这些基本概念就不一一进行说明了。 二叉树性质: ... -
《剑指offer》第五十五题(平衡二叉树)
2021-01-17 15:11:35//面试题55(二):平衡二叉树//题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中//任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。#include#include"BinaryTree.h"//=====... -
数据结构之——平衡二叉树(内容详解)
2019-12-29 19:17:16平衡二叉树也叫AVL树,它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和左子树的高度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。 二、结构 如基本概念所树,它具有一... -
平衡二叉树(AVL)
2021-09-04 18:02:37平衡二叉树,全称为平衡二叉搜索树 它是由苏联数学家Adelson-Velsky 和 Landis提出来的,因此平衡二叉树又叫AVL树 平衡二叉树的定义是一种递归定义,要求每个节点都具有以下特性: 可以是一棵空树 左子树和右子树... -
数据结构之平衡二叉树
2020-12-25 14:36:27前言需求介绍 题:我们从一个数列(1,2,3,4,5,6),来说明构成二叉排序树的一些问题 左子树全部为空, 从形式图所看,...平衡二叉树也叫平衡二叉搜索树(Self balancing binary searchtree)又被称为AVL树, 可以保证查询 -
平衡二叉树的旋转以及简便方法
2021-04-06 22:24:33刚开始听这个平衡二叉树的旋转,一听就蒙了,后来看了很多视频,有很多的说法。下面来介绍平衡二叉树 平衡二叉树:就是每个节点的平衡因子(Balance Factor)(以下简称BF)的绝对值小于等于1,即为0或1。 而BF就是每... -
平衡二叉树
2021-07-16 16:13:39(1)含有20个结点的平衡二叉树的最大深度为( ) 解:深度最大,也就意味着每层的结点数最少,而且要保持平衡 深度为1时,总结点数1,f(1)=1 深度为2时,总结点数为2,f(2)=2 深度为3时,总结点为4,f(3)=4 ... -
数据结构与算法(三) 03-平衡二叉树及二叉树的经典题型
2021-01-08 13:40:14平衡二叉树、二叉树的经典题 1 平衡二叉树 题目 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 平衡二叉树:每个子树的深度之差不超过1 思路 后续遍历二叉树,在遍历二叉树每个节点前都会遍历其左右子树 ... -
平衡二叉树的左旋和右旋
2021-04-15 09:32:36平衡二叉树(平衡二叉搜索树) 本文章是我的库存文章,本来不发的,但还是发吧,请跳到第7节,那才是讲左旋和右旋的。至于前面的复习树要看也可以,只是一堆概念,并不复杂。 复习树 1. 树的概念 生活中的树跟... -
数据结构与算法分析笔记与总结(java实现)--二叉树5:平衡二叉树判断练习题
2017-02-15 17:30:29数据结构与算法分析笔记与总结(java实现)--二叉树5:平衡二叉树判断练习题 -
平衡二叉树(AVL)的4种插入调整过程
2019-07-10 22:06:54平衡二叉树(AVL)的4种插入调整过程 平衡二叉树定义: 在插入中为了保证二叉排序树的性能,规定在插入和删除二叉树结点时,要保证任意结点的左、右子树的高度差的绝对数值不超过1,这样的二叉树被称为平衡二叉树... -
面试被问到平衡二叉树如何平衡?
2020-07-04 12:03:30...平衡二叉树的递归定义:平衡二叉树是一棵二叉树,其可以为空,或满足如下2个性质:①左右子树深度之差的绝对值不大于1。②左右子树都是平衡二叉树。 平衡因子的概念:结点的平衡因子 = 结点的 -
[数据结构]平衡二叉树怎么旋转?怎么画?全过程--(刚学会防止忘记)
2020-11-20 21:24:32【数据结构】平衡二叉树怎么自己画? 是什么? 要了解平衡二叉树,先得了解什么是二叉树? 二叉树定义: 在计算机中,二叉树是每一个节点最多有两... -
JS版数据结构之 树、搜索二叉树、平衡二叉树、红黑树
2021-08-24 22:32:39遍历(1)先序遍历(2)中序遍历(3)后序遍历(4)最大值、最小值、查找四、平衡二叉树1.定义五、红黑树1.定义2.特性 一、树 双亲表示法: 顺序存储各个结点时,给各个结点添加一个变量,记录其父结点的位置。 孩子... -
二叉树的题库
2020-02-18 11:52:331.在图B-1所示的平衡二叉树中,插入关键字48后得到一棵新平衡二叉树。在新平衡二叉树中,关键字37所在结点的左、右子结点中保存的关键字分别是()。//24,53 解释:插入48以后,该二叉树根结点的平衡因子由-1变为-2... -
二叉排序树与平衡二叉树的实现
2010-12-26 15:25:31题 目 二叉排序树与平衡二叉树的实现 1、课程设计的目的 使学生进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法。 使学生掌握软件设计的基本内容... -
二叉树常见面试题小结
2021-05-21 12:19:19这篇文章是二叉树系列的终结篇,总结了一下二叉树常见的手撕面试题,题目多来源于剑指offer,考察的也多数基于对二叉树前中后序遍历的理解,下面具体看题目:public class TreeNode {int val;TreeNode left = null;... -
【数据结构】----平衡二叉树怎么自己画?
2017-01-08 19:23:27【数据结构】平衡二叉树怎么自己画? 是什么? 要了解平衡二叉树,先得了解什么是二叉树? 二叉树定义: 在计算机中,二叉树是每一个节点最多有两个子树的结构。通常子树被称作“左子树(left subtree)”... -
平衡二叉树操作的演示
2019-04-18 22:59:131.需求分析 ~~~~ ...(1) 初始,平衡二叉树为空树,操作界面给种出查找、插入和删除三操作供选择。每种操作均要提示输入关键字。每次插入或删除一个结点后,应更新... -
PTA习题:练习4.2 平衡二叉树的根 (25分)
2020-09-04 16:08:28练习4.2 平衡二叉树的根 (25分) 将给定的一系列数字插入初始为空的AVL树,请你输出最后生成的AVL树的根结点的值。 输入格式: 输入的第一行给出一个正整数N(≤20),随后一行给出N个不同的整数,其间以空格分隔。 ... -
《二叉树刷题计划》——平衡二叉树
2022-05-17 07:25:42二叉树相关OJ题目——二叉树的高度,平衡二叉树的判断 -
前端二叉树面试题
2020-05-10 15:15:25文章目录二叉树常见题型二叉树的中序遍历前序遍历后序遍历重建二叉树对称的二叉树 二叉树 二叉树是树结构中一种典型的树状结构,每个节点最多只能有两个子节点,一个是左侧子节点,一个是右侧子节点。 二叉树中又有... -
Java基础题:平衡二叉树(平衡因子)
2020-04-01 10:25:44平衡二叉树:所有子树的高度差<=1 平衡因子:高度差 分支节点不包括叶子节点 图片来源:https://www.nowcoder.com/questionTerminal/d18b23d6f00c41eba5aba6587592d531