检查一个二叉树是否平衡的算法分析与C++实现
今天面试一个实习生,就想既然是未出校园,那就出一个比较基础的题吧,没想到答的并不如人意,对于树的操作完全不熟悉,因此此题算是未作答。原来我想看一下他分析问题的思路,优化代码的能力。接下来会把最近半年我出的面试题整理出来,以来share给其它同事,而来算是自己校园记忆的一个总结,毕竟自己在项目中已经很久未用到这些知识。其实很多题目都是来源于CareerCup.com。这上面汇集了许多IT名企的面试笔试题目,非常值得找工作的人学习。
言归正传,什么是二叉树是否平衡的定义,如果面试者不知道,那肯定要提出来,而不是简简单单说我对树不熟悉,或者找其他更多更多的理由。
其实可以根据平衡的定义,直接递归访问整棵树,计算子树的高度。
struct TreeNode{
TreeNode *leftChild;
TreeNode *rightChild;
int data;
};
int getHeight(const TreeNode* root){
if( root == nullptr){
return 0;
}
return max(getHeight(root->leftChild), getHeight(root->rightChild)) + 1;
}
bool isBalanced(const TreeNode* root){
if( root == nullptr){
return true;
}
int heightDiff = abs(getHeight(root->leftChild) - getHeight(root->rightChild));
if( heightDiff > 1){
return false;
}
else{
return isBalanced(root->leftChild) && isBalanced(root->rightChild);
}
}
如果开始能给出这个解法那是可以接受的。但是,由于同一个node的高度会被重复计算,因此效率不高。算法复杂度是O(n*logn)。接下来,我们要改进这个算法,使得子树的高度不再重复计算:我们通过删减重复的getHeight(const TreeNode*)调用。其实getHeight不单可以计算子树的高度,其实还可以判断子树是否的平衡的,如果不平衡怎么办?直接返回-1。那该递归调用就可以结束了。
因此,改进的算法就是从root开始递归检查每个子树的高度,如果子树是平衡的,那么就返回子树的高度,否则返回-1:递归结束,树是不平衡的。
int checkHeight(const TreeNode* root){
if( root == nullptr){
return 0;
}
// check the left subtree is balanced or not.
int leftHeight = checkHeight(root->leftChild);
if( leftHeight == -1 ){
return -1;
}
// check the right subtree is balanced or not.
int rightHeight = checkHeight(root->rightChild);
if( rightHeight == -1){
return -1;
}
// check the current tree is balanced or not.
int diff = leftHeight - rightHeight;
if( abs(diff) > 1){
return -1;
}
else{
// return the tree height.
return max(leftHeight, rightHeight) + 1;
}
}
bool isBalanced(const TreeNode* root){
return ( checkHeight(root) == -1 )? false:true;
}
由于每个node只会访问一次,因此算法时间复杂度为O(n)。但是需要额外的O(logn)的空间。
检查一个二叉树是否平衡的算法分析与C++实现的更多相关文章
- 【遍历二叉树】10判断二叉树是否平衡【Balanced Binary Tree】
平衡的二叉树的定义都是递归的定义,所以,用递归来解决问题,还是挺容易的额. 本质上是递归的遍历二叉树. ++++++++++++++++++++++++++++++++++++++++++++++++ ...
- 在javascript中检查一个值是否为integer
integer 类型在javascript中很奇怪.ECMAScript技术规格说明书中,它是以概念的形式存在.number类型包括浮点型(floating )和整形(integer )不包括小数(详 ...
- 《Python CookBook2》 第一章 文本 - 过滤字符串中不属于指定集合的字符 && 检查一个字符串是文本还是二进制
过滤字符串中不属于指定集合的字符 任务: 给定一个需要保留的字符串的集合,构建一个过滤函数,并可将其应用于任何字符串s,函数返回一个s的拷贝,该拷贝只包含指定字符集合中的元素. 解决方案: impor ...
- Java 高效检查一个数组中是否包含某个值
如何检查一个数组(未排序)中是否包含某个特定的值?在Java中,这是一个非常有用并又很常用的操作.同时,在StackOverflow中,有时一个得票非常高的问题.在得票比较高的几个回答中,时间复杂度差 ...
- LeetCode 606. Construct String from Binary Tree (建立一个二叉树的string)
You need to construct a string consists of parenthesis and integers from a binary tree with the preo ...
- 【easy】110. Balanced Binary Tree判断二叉树是否平衡
判断二叉树是否平衡 a height-balanced binary tree is defined as a binary tree in which the depth of the two su ...
- Java如何检查一个线程停止或没有?
Java如何检查一个线程停止或没有? 解决方法 下面的示例演示如何使用 isAlive()方法检查一个线程是否停止. public class Main { public static void ma ...
- <!-- str.startsWith('胡') 检查一个 字符串中是否有某字符 返回true false -->& vh 属性
1.<!-- str.startsWith('胡') 检查一个 字符串中是否有某字符 返回true false --> 2. vh 分享到选择其它项 复制本页链接 版本:CSS3 补 ...
- 七、如何在Java中高效检查一个数组是否含有一个值
如何检查一个数组(非排序的)是否包含特定的值.这是个非常有用或经常被在Java中使用.这是个在Stack Overflow中高得票的问题.在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非 ...
随机推荐
- requestAnimationFrame之缓动的应用
之前需要使用的定时器的时,立马想到的是setInterval(),用着用着就成为习惯,并没有遇到什么不妥之处.习惯性的操作往往容易让一个人拒绝尝试一些其他的方法.现在的方法用得好好的,没事干啥找其他法 ...
- Java并发中的CopyOnWrite容器
Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...
- jsp&servlet——session监听
session监听,需要实现HttpSessionAttributeListener接口 attributeAdded:监听添加session attributeRemoved:监听删除session ...
- 数据挖掘_requests模块的post方法
前面已经跟大家讲了requests模块的get方法,这一篇文章我们要介绍的是requests模块中的另一个比较常用的方法,post方法 post方法的形式相比于get要复杂一些,这时因为post在提交 ...
- bootstrap table 和 x-editable 使用方法
最近需要做一些数据表格,有同事推荐EasyUI,但经过比较还是选择了Bootstrap,一款极为强大的表格组件,基于Bootstrap 的 jQuery .本文还将介绍Bootstrap-editab ...
- Winform DevExpress控件库(一) DevExpress控件库的安装与新建第一个DevExpress项目
前言:因为这段时间要接触到DevExpress控件库,而我本身甚至对winform的控件都了解甚少,所以处在学习中,写下博客主要是为了方便后期的回顾,当然也可以给一些新人第一次接触时做为学习的参考,以 ...
- HOG OpenCV 代码片段
直接上代码: #include <opencv2/opencv.hpp> using namespace cv; #include <cmath> using namespac ...
- ejabberd mod_echo 解析
ejabberd mod_echo 解析(金庆的专栏 2016.8)按开发入门的说明,mod_echo是最简单的模块之一.https://docs.ejabberd.im/developer/当然 m ...
- 28 自定义View流式布局
流式布局每行的行高以本行中最高的元素作为高,如果一个元素放不下到一行时直接到第二行 FlowLayoutView package com.qf.sxy.customview05.widget; imp ...
- Xcode7.3.1中SKAudioNode在Scene转换后无声的问题
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在新的Xcode中之前可以正常运行的SKAudioNode代码 ...