今天面试一个实习生,就想既然是未出校园,那就出一个比较基础的题吧,没想到答的并不如人意,对于树的操作完全不熟悉,因此此题算是未作答。原来我想看一下他分析问题的思路,优化代码的能力。接下来会把最近半年我出的面试题整理出来,以来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++实现的更多相关文章

  1. 【遍历二叉树】10判断二叉树是否平衡【Balanced Binary Tree】

    平衡的二叉树的定义都是递归的定义,所以,用递归来解决问题,还是挺容易的额. 本质上是递归的遍历二叉树. ++++++++++++++++++++++++++++++++++++++++++++++++ ...

  2. 在javascript中检查一个值是否为integer

    integer 类型在javascript中很奇怪.ECMAScript技术规格说明书中,它是以概念的形式存在.number类型包括浮点型(floating )和整形(integer )不包括小数(详 ...

  3. 《Python CookBook2》 第一章 文本 - 过滤字符串中不属于指定集合的字符 && 检查一个字符串是文本还是二进制

    过滤字符串中不属于指定集合的字符 任务: 给定一个需要保留的字符串的集合,构建一个过滤函数,并可将其应用于任何字符串s,函数返回一个s的拷贝,该拷贝只包含指定字符集合中的元素. 解决方案: impor ...

  4. Java 高效检查一个数组中是否包含某个值

    如何检查一个数组(未排序)中是否包含某个特定的值?在Java中,这是一个非常有用并又很常用的操作.同时,在StackOverflow中,有时一个得票非常高的问题.在得票比较高的几个回答中,时间复杂度差 ...

  5. 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 ...

  6. 【easy】110. Balanced Binary Tree判断二叉树是否平衡

    判断二叉树是否平衡 a height-balanced binary tree is defined as a binary tree in which the depth of the two su ...

  7. Java如何检查一个线程停止或没有?

    Java如何检查一个线程停止或没有? 解决方法 下面的示例演示如何使用 isAlive()方法检查一个线程是否停止. public class Main { public static void ma ...

  8. <!-- str.startsWith('胡') 检查一个 字符串中是否有某字符 返回true false -->& vh 属性

    1.<!-- str.startsWith('胡')  检查一个 字符串中是否有某字符 返回true false --> 2. vh 分享到选择其它项   复制本页链接 版本:CSS3 补 ...

  9. 七、如何在Java中高效检查一个数组是否含有一个值

    如何检查一个数组(非排序的)是否包含特定的值.这是个非常有用或经常被在Java中使用.这是个在Stack Overflow中高得票的问题.在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非 ...

随机推荐

  1. tf.nn.conv2d 和 tf.nn.max_pool 中 padding 分别为 'VALID' 和 'SAME' 的直觉上的经验和测试代码

    这个地方一开始是迷糊的,写代码做比较分析,总结出直觉上的经验. 某人若想看精准的解释,移步这个网址(http://blog.csdn.net/fireflychh/article/details/73 ...

  2. 独立完成一个移动点餐wap后的小结

    1.技术栈:vue  vue-router  vuex  Mint-ui  better-scroll; 2.实践总结: a.单页应用不重新渲染组件问题:组件在初次渲染后不会重新渲染,此时当从某个路径 ...

  3. 解决问题redis问题:ERR Client sent AUTH, but no password is set

    是的,这又是一个坑爹的问题. 明明在redis.conf中设置了密码,而且redis还启动了,为什么说没有密码呢? 大家都知道linux下启动redis有很多种方法, 其中有 ./redis-serv ...

  4. 检测linux vps是xen openvz还是kvm的方法

    很多时候不知道自己买的vps是那种虚拟化技术,怕给商家忽悠了,下面给大家介绍下怎么简单的判断自己vps的虚拟化技术. 1.通过系统上的相关目录或文件判断 ll /proc/   ps: /proc目录 ...

  5. Android重绘ListView高度

    Android重绘ListView高度 经常会有这样需求,需要ListView默认将所有的条目显示出来,这就需要外层使用ScrollView,ScrollView里面放置一个重绘高度的ListView ...

  6. 使用Kubernetes需要注意的一些问题(FAQ of k8s)

    本篇文章并不是介绍K8S 或者Docker的,而仅仅是使用过程中一些常见问题的汇总. 重启策略:http://kubernetes.io/docs/user-guide/pod-states/, 对于 ...

  7. SpriteKit塔防游戏动态改变防御塔价格标签的颜色

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 本篇blog在DinoDefense塔防游戏基础之上做一处小的 ...

  8. Android简易实战教程--第二十一话《内容观察者监听数据库变化》

    当数据库的数据发生改变,我们又想知道具体改变的情况时,就需要对数据库的变化情况做一个监控.这个任务,就由内容观察者来完成.下面这个案例,为短信数据库注册内容观察者,来监控短信的变化情况,当短信数据库发 ...

  9. Android动态换肤(二、apk免安装插件方式)

    在上一篇文章Android动态换肤(一.应用内置多套皮肤)中,我们了解到,动态换肤无非就是调用view的setBackgroundResource(R.drawable.id)等方法设置控件的背景或者 ...

  10. Android开发学习之路--RxAndroid之操作符

      学习了RxAndroid的一些基本知识,上篇文章也试过了RxAndroid的map操作符,接着来学习更多的操作符的功能吧.   操作符就是为了解决对Observable对象的变换的问题,操作符用于 ...