检查一个二叉树是否平衡的算法分析与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中高得票的问题.在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非 ...
随机推荐
- centos 6安装opencv
昨天装好的,今天有些细节已经记不起来里,大致写一下吧. 首先,从opencv官网下载linux的opencv-2.4.9安装包,下载地址:http://jaist.dl.sourceforge.net ...
- 转:rabbitmq——用户管理
原文:http://my.oschina.net/hncscwc/blog/262246?p={{currentPage-1}} 安装最新版本的rabbitmq(3.3.1),并启用managemen ...
- Rabbitmq集群
分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 Rabbitmq集群高 ...
- 【mybatis深度历险系列】mybatis中的输入映射和输出映射
在前面的博文中,小编介绍了mybatis的框架原理以及入门程序,还有mybatis中开发到的两种方法,原始开发dao的方法和mapper代理方法,今天博文,我们来继续学习mybatis中的相关知识,随 ...
- 凸函数与Jensen不等式
这个是在凸优化里面看的,在EM算法中看有用到,所以用latex写了篇回忆用的小短文,现在不会把latex产生的pdf怎么转变成放到这里的内容. 所以我选择直接贴图. 这个pdf可以在我的资源里找到. ...
- Xcode无法安装基于ruby的插件问题的解决
Xcode有时需要安装一些第三方插件,很多插件是基于ruby的,确切的说是基于ruby gem的! 但是在国内有一个很尴尬的情况,就是官方的gems网站:https://rubygems.org 的安 ...
- androidApp的完全退出
思路:搜集整个工程所有的activity,通过循环把工程中所有的activity都关闭. 搜集工程中的activity,可以由单例模式实现, [java] view plaincopy import ...
- T-SQL动态查询(4)——动态SQL
接上文:T-SQL动态查询(3)--静态SQL 前言: 前面说了很多关于动态查询的内容,本文将介绍使用动态SQL解决动态查询的一些方法. 为什么使用动态SQL: 在很多项目中,动态SQL被广泛使用甚至 ...
- 22 Notification样式设置内部按钮点击事件
package com.exam1ple.demo1; import android.app.Activity; import android.app.NotificationManager; imp ...
- JAVA面向对象-----super关键字
JAVA面向对象-–super关键字 1:定义Father(父类)类 1:成员变量int x=1; 2:构造方法无参的和有参的,有输出语句 2:定义Son类extends Father类 1:成员变量 ...