《剑指offer(第二版)》面试题55——判断是否为平衡二叉树
一.题目大意
输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树)。
二.题解
《剑指offer》上给出了两种解决方式:
1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点为根节点的子树的高度,通过判断左右子树的高度差是否大于1来判断是否为AVL树。其中计算子树的高度,利用了TreeDepth函数(具体可见《剑指offer(第二版)》P272).其中TreeDepth的思想如下:
(1)计算一颗二叉树的高度,可以将该问题转化成求子树的高度+1。如果根节点只有左子树的话,那么该二叉树的高度=左子树的高度+1.
(2)如果根节点只有右子树的话,那么该二叉树的高度=右子树的高度+1.
(3)如果根节点既有左子树又有右子树的话,那么该二叉树的高度等于左子树和右子树中高度的较大值加1.
这很显然利用分治的思想就可以解决。
利用TreeDepth函数判断是否为AVL树的话,很多节点往往会重复遍历多次,所以效率会比较低。
2.第二种《剑指offer》上给出的思想是:利用后序遍历的思想,每次遍历到某个节点时,它的左右子树一定已经遍历完了,所以只需在遍历每个节点的时候记录该节点的深度(某一节点的深度等于该节点到叶节点的长度),就可以一边遍历一边判断每个节点是否平衡。
代码可参考书上P274的带代码,但我觉得这种方法不够形象,所以便有了第3种方法。
3.这种方法是这篇文章强调的重点。我们可以利用TreeDepth函数的思想,同样也是分治的思想:
要判断一棵二叉树是否为AVL树,只需判断它的左子树和右子树是否都为AVL数,如果都是AVL树的话,那么这棵树一定是AVL数;对于左子树和右子树的判断进行同样的操作。这就将父问题转换成了一系列的子问题,一旦子问题中有一个不满足的,就返回结果。
代码如下:
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot == nullptr)//此处需要注意,空树的话也是AVL树
return true;
return GetAVLDepth(pRoot) != -1;//返回-1相当于不是AVL树
}
int GetAVLDepth(TreeNode* pRoot)
{
if(pRoot == nullptr)//空的情况返回0
return 0;
int left = GetAVLDepth(pRoot->left);
if(left == -1)//如果子树不是AVL树的话,立马返回,此处相当于剪枝,这步是必须要加的,否则可能出错
return -1;
int right = GetAVLDepth(pRoot->right);
if(right == -1)
return -1;
return abs(left - right) > 1 ? -1 : (max(right,left) + 1);//只有左右子树都为AVL树的话才会返回这棵树的高度
}
};
这种方法是的思想本质与求二叉树的高度的思想是一致的,只不过在返回时,只有左右子树都为AVL树的话才会返回数的高度,否则返回-1(即非AVL树),所以值得回味与思索。还有一点需要注意的是,当根节点为空时,此时是棵空树,但它也是AVL树。最为重要的一点是,如果遇到左子树或者右子树不是AVL树的话,应立马返回-1,否则,后续处理可能出错。
方法3相比方法2在代码上更容易理解,更加形象些。
《剑指offer(第二版)》面试题55——判断是否为平衡二叉树的更多相关文章
- 经典面试题目——找到第n个丑数(参考《剑指offer(第二版)》面试题49)
一.题目大意 给你一个数n,要求返回第n个丑数.其中,丑数的定义如下: 丑数是指只包含因子2.3和5的数.(数字1也是丑数,不过是个特例)引用<剑指offer>上的话来说,对于一个数M,如 ...
- 《剑指offer(第二版)》——面试题36:二叉搜索树与双向链表
具体的题目大意和参考思路在此处不详述(见<剑指offer>),实质就是在中序遍历的过程中调整指针的指向,关于中序遍历有递归和非递归两种操作,所以此处也用了两种方法. 方法1(递归法): 代 ...
- 《剑指offer(第二版)》面试题60——n个骰子的点数
一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释 ...
- 《剑指offer(第二版)》面试题64——求1+2+...+n
一.题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句 (即三元运算符,A? B : C) 二.题解 虽然求和问 ...
- 结合《剑指offer(第二版)》面试题51来谈谈归并排序
一.题目大意 给定一个数组A,对于数组A中的两个数字,如果排在前面的一个数字大于(必须大于,等于不算)后面的数字,则这两个数字组成一个逆序对.要求输出数组A中的逆序对的总数.例如,对于数组{7,5,6 ...
- 《剑指offer 第二版》题解
剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试 ...
- 剑指offer第二版-10.斐波那契数列
面试题10:斐波那契数列 题目要求: 求斐波那契数列的第n项的值.f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2) n>1 思路:使用循环从下往上计算数列. 考点:考察对递归 ...
- 剑指offer第二版-5.替换空格
面试题5:替换空格 题目要求: 实现一个函数,把字符串中的每个空格都替换成“%20”,已知原位置后面有足够的空余位置,要求改替换过程发生在原来的位置上. 思路: 首先遍历字符串求出串中空格的数量,求出 ...
- 剑指offer第二版-3.数组中重复的数
面试题3:数组中重复的数 题目要求: 在一个长度为n的数组中,所有数字的取值范围都在[0,n-1],但不知道有几个数字重复或重复几次,找出其中任意一个重复的数字. 解法比较: /** * Copyri ...
随机推荐
- HihoCoder - 1807:好的数字串 (KMP DP)
Sample Input 6 1212 Sample Output 298 给定一个数字字符串S,如果一个数字字符串(只包含0-9,可以有前导0)中出现且只出现1次S,我们就称这个字符串是好的. 例如 ...
- Contest1036 - 2017西安电子科技大学程序设计新生赛网络预选赛
一名大三older 希望能帮助大一萌新...加油 xiandianer!!!!; xdoj 1260 (B) 水题 用了一下STL (好长啊...) #include<iostream> ...
- ACM-ICPC 2018 沈阳赛区网络预赛-K:Supreme Number
Supreme Number A prime number (or a prime) is a natural number greater than 11 that cannot be formed ...
- 一次scrapy成功停止的信息
2017-11-05 18:52:42 [scrapy.core.engine] INFO: Closing spider (finished)2017-11-05 18:52:42 [scrapy. ...
- json(传输格式)、异步加载、时间线
xml:过去传输的数据格式 json:现在的传输数据格式,属性名加双引号来区别,其实也是对象,传输的是个字符串,其实就是json 前端JSON.stringfy(obj) 然后传给后台 后台传回来的j ...
- struts2 中的数据访问servletAPI
ActionContext包含其他数据对象,包括值栈 每次请求都会创建一个ActionContext对象 通过ActionContext访问数据 在action中读取 在jsp页面中读取 1 ...
- 思科模拟器——允许远程telnet连接控制路由器/交换机
环境如下: 路由器配置如下.interface f0/0 配置该端口,ip address 192.168.1.1 255.255.255.0 配置ip,no shut激活,line vty 0 4 ...
- oracle实用命令入门
登录oracle(需要在oracle用户下) 执行sqlplus,然后输入用户名和密码就可以了,如果是第一次使用oracle的话,可以直接使用sqlplus / as sysdba免密码以管理员的身份 ...
- Cassandra基础3
cassandra读性能优化:1.禁用read repair每次读操作,无论读请求设置读一个节点还是多个节点,cassandra返回给客户端最新的数据后,都会后台对比所有副本的数据并对差异数据进行修复 ...
- Web APi入门之Self-Host寄宿及路由原理 【转载】
前言 刚开始表面上感觉Web API内容似乎没什么,也就是返回JSON数据,事实上远非我所想,不去研究不知道,其中的水还是比较深,那又如何,一步一个脚印来学习都将迎刃而解. Self-Host 我们知 ...