《剑指offer》面试题39 二叉树的深度(java)
摘要:
今天翻到了《剑指offer》面试题39,题目二中的解法二是在函数的参数列表中通过指针的方式进行传值,而java是没有指针的,所以函数要进行改造。然而我翻了下别人的java版本(我就想看看有什么高大上的改造,毕竟要传递多个参数,是不是会涉及到那么一点点设计模式呢?),简直不能忍了,我只能用一句话形容:“一本正经的胡说八道”,不过我就是喜欢看你胡说八道还迷之自信的样子。
下面吐槽一下这个版本的java代码:
//高效率的判断是否是一棵平衡二叉树
public boolean isBalanced2(BinaryTreeNode root){
int depth = 0;
return isBalanced2(root,depth);
}
public boolean isBalanced2(BinaryTreeNode root,int depth){
if(root == null){
depth = 0;
return true;
}
int left = 0,right = 0;
if(isBalanced2(root.leftNode,left) && isBalanced2(root.rightNode,right)){
int diff = left-right;
if(diff <= 1 && diff >= -1){
depth = 1+(left > right?left : right);
return true;
}
}
return false;
}
这个文章的原始链接我就不发了,保留一点人品。关键是特么CSDN竟然把他作为百度搜索第一条置顶了,可见人气是最高的,看看作者发帖历史(好像还有那么一点小屌),我TM差点就信了。这个哥们连函数参数的复制传值都不懂啊!怎么学的编程,还发帖误导广大小学生,简直不能忍。我看也不用参考别人的代码了,自己写一个吧。
原题一:输入一颗二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根,叶子结点)形成一条路径,最长路径的长度为树的深度。
输入样例:
1
2 3
4 5 6
7
源代码:
class BinaryTreeNode{ public int data;
public BinaryTreeNode left;
public BinaryTreeNode right; public BinaryTreeNode(){
data = 0;
left = null;
right = null;
}
}
public class Question_39 {
//----递归求二叉树深度----
public static int treeDepth(BinaryTreeNode root){
if(root == null){
return 0;
}
int left = treeDepth(root.left);
int right = treeDepth(root.right); return (left>right)?(left+1):(right+1);
} public static void main(String[] args) {
// TODO Auto-generated method stub
BinaryTreeNode node1 = new BinaryTreeNode();
BinaryTreeNode node2 = new BinaryTreeNode();
BinaryTreeNode node3 = new BinaryTreeNode();
BinaryTreeNode node4 = new BinaryTreeNode();
BinaryTreeNode node5 = new BinaryTreeNode();
BinaryTreeNode node6 = new BinaryTreeNode();
BinaryTreeNode node7 = new BinaryTreeNode(); node1.data = 1;
node2.data = 2;
node3.data = 3;
node4.data = 4;
node5.data = 5;
node6.data = 6;
node7.data = 7; node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node5.left = node7;
node3.right = node6; System.out.println("递归求二叉树深度: "+treeDepth(node1)); }
}
这道题比较简单,没什么好说的。
题目二:输入一颗二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一颗平衡二叉树。
方法一:需要重复遍历多次的解法,简单但不足以打动面试官
public static boolean isBalanced_1(BinaryTreeNode root){
if(root==null){
return true;
}
int left = treeDepth(root.left);
int right = treeDepth(root.right);
int diff = left - right;
if(diff>1||diff<-1){
return false;
}
return isBalanced_1(root.left)&&isBalanced_1(root.right);
}
该方法简洁,但是一个结点会被重复遍历多次,时间效率不高。
方法二:每个结点只遍历一次,面试官喜欢
class Tuple{
private boolean isBalanced;
private int depth; public Tuple(){}
public Tuple(boolean isBalanced, int depth) {
super();
this.isBalanced = isBalanced;
this.depth = depth;
}
//-----isBalanced,Getters and Setters----
public boolean getIsBalanced() {
return isBalanced;
}
public void setIsBalanced(boolean isBalanced) {
this.isBalanced = isBalanced;
}
//-----depth,Getters and Setters----
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
} }
//----判断平衡二叉树,每个结点只遍历一次----
private static Tuple isBalanced(BinaryTreeNode root){
if(root==null){
Tuple tuple = new Tuple();
tuple.setIsBalanced(true);
tuple.setDepth(0);
return tuple;
}
Tuple left = isBalanced(root.left);
Tuple right = isBalanced(root.right); if(left.getIsBalanced()&&right.getIsBalanced()){
int diff = left.getDepth()-right.getDepth();
if(diff<=1&&diff>=-1){
return new Tuple(true,(left.getDepth()>right.getDepth()?left.getDepth():right.getDepth()) + 1 );
}
}
return new Tuple(false,-1);
}
public static boolean isBalancedBinaryTree(BinaryTreeNode root){
Tuple tuple = isBalanced(root);
return tuple.getIsBalanced();
}
在上面的代码中,我们使用后序遍历的方式遍历整颗二叉树。在遍历某结点的左右子结点之后,我们可以根据它的左右子结点的深度判断它是不是平衡的,并得到当前结点的深度。当遍历到根结点的时候,也就判断了整颗二叉树是不是平衡二叉树。由于要传递两个参数,一般的使用返回值的方法是行不通的,而且Java并不存在指针和简单数据类型的引用传值。一般的高级语言(如Python)会有元组这么一个概念(Java没有那就自己定义一个),既然只能返回一个值,那就返回一个复合类型的,函数改造完成~
我想说的是,每个入了门的程序员都知道参数是复制传值,在C/C++中只能用指针和引用的方式从参数列表中传递或获取值,在Java中,除了基本数据类型和String类型外,也是引用传值。但是基本数据类型传进函数体你改动了有什么意义?你只是改动了一个副本。为了呵护祖国下一代程序员的健康成长,老夫专门抽时间写了一篇博客(抠鼻),打击不良之风~ 本来想和平衡二叉树结合一起写一篇文章,但是平衡二叉树TMD代码一下子要写500多行,我表示受到了惊吓,有机会再说吧
《剑指offer》面试题39 二叉树的深度(java)的更多相关文章
- 剑指offer【08】- 二叉树的深度(java)
题目:二叉树的深度 考点:知识迁移能力 题目描述:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 牛客网上的剑指offer题, ...
- 剑指Offer:面试题19——二叉树的镜像(java实现)
问题描述: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树结点定义为: public class TreeNode { int val = 0; TreeNode left = null; Tr ...
- C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解
剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...
- C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解
剑指offer 面试题39:判断平衡二叉树 提交网址: http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...
- 剑指Offer - 九度1350 - 二叉树的深度
剑指Offer - 九度1350 - 二叉树的深度2013-11-23 00:54 题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的 ...
- 【剑指offer】55 - I. 二叉树的深度
剑指 Offer 55 - I. 二叉树的深度 知识点:二叉树,递归 题目描述 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长度为树 ...
- 剑指Offer:面试题20——顺时针打印矩阵(java实现)
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数 字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1, ...
- 剑指offer面试题4 替换空格(java)
注:利用java中stringBuilder,append,length方法很方便的解决字符串问题 /* * 剑指offer 替换空格 * xsf * */ /*开始替换空格的函数,length为原数 ...
- 剑指Offer面试题39(Java版):二叉树的深度
题目:输入一棵二叉树的根节点,求该数的深度. 从根节点到叶结点依次进过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度. 比如.例如以下图的二叉树的深度为4.由于它从根节点到叶结点的最 ...
- 剑指Offer:面试题25——二叉树中和为某一值的路径(java实现)
问题描述: 输入一棵二叉树和一个整数,打印出二叉树中结点指的和为输入整数的所有路径.从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.二叉树结点的定义如下: public class Tree ...
随机推荐
- 四则运算2及PSP0设计项目计划
时间比较紧,我简单写写我的设计思路: 题目在四则运算1的基础上控制产生题目的数量,这个可以用变量控制:打印方式也可选用变量控制,程序的关键是括号的生成.我们可以将整个四则运算式看成()+()的模型,然 ...
- 【数据预处理】TIMIT语料库WAV文件转换
1 问题描述 这两天复现代码.先构造数据集,纯净语音.不同噪声.不同SNR的混合语音.其中纯净语音由两部分组成,IEEE corpus和TIMIT. 一开始我用MATLAB中的audioread读取音 ...
- web06-PanduanLogin
电影网站:www.aikan66.com 项目网站:www.aikan66.com 游戏网站:www.aikan66.com 图片网站:www.aikan66.com 书籍网站:www.aikan66 ...
- mvc 页面方法学习-RenderBody方法
教程地址:https://docs.microsoft.com/zh-cn/aspnet/mvc/overview/getting-started/introduction/adding-a-view
- 结对项目-小学生四则运算系统(GUI)
Coding克隆地址:https://git.coding.net/FrrLolix/CalGUI.git 伙伴博客:http://www.cnblogs.com/wangyy39/p/8763244 ...
- maven导入项目时出现“Cannot read lifecycle mapping metadata …… invalid END header (bad central directory offset)pom”错误的解决方法
出现该错误是因为jar包版本不匹配,比如linux上的jar包导入到windows上了.可以将.m2\repository的org.apache.maven.plugins删掉然后让maven重新下载 ...
- iOS-UICollectionViewLayout方法介绍
注意:UICollectionView的自定义功能就是自己去实现UICollectionViewLayout的子类,然后重写相应的方法来实现Cell的布局 1.当布局首次被加载时会调用prepareL ...
- ssh结合使用
springxml配置 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=& ...
- PAT 1053 住房空置率
https://pintia.cn/problem-sets/994805260223102976/problems/994805273284165632 在不打扰居民的前提下,统计住房空置率的一种方 ...
- [51CTO]反客为主 ,Linux 成为微软 Azure 上最流行的操作系统
反客为主 ,Linux 成为微软 Azure 上最流行的操作系统 [世界上唯一确定不变的就是世界在不停的变化] 三年前,微软云计算 Azure 平台 CTO Mark Russinovich 说有四分 ...