摘要:

今天翻到了《剑指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)的更多相关文章

  1. 剑指offer【08】- 二叉树的深度(java)

    题目:二叉树的深度 考点:知识迁移能力 题目描述:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 牛客网上的剑指offer题, ...

  2. 剑指Offer:面试题19——二叉树的镜像(java实现)

    问题描述: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树结点定义为: public class TreeNode { int val = 0; TreeNode left = null; Tr ...

  3. C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解

    剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...

  4. C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解

    剑指offer 面试题39:判断平衡二叉树 提交网址:  http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...

  5. 剑指Offer - 九度1350 - 二叉树的深度

    剑指Offer - 九度1350 - 二叉树的深度2013-11-23 00:54 题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的 ...

  6. 【剑指offer】55 - I. 二叉树的深度

    剑指 Offer 55 - I. 二叉树的深度 知识点:二叉树,递归 题目描述 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长度为树 ...

  7. 剑指Offer:面试题20——顺时针打印矩阵(java实现)

    题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数 字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1, ...

  8. 剑指offer面试题4 替换空格(java)

    注:利用java中stringBuilder,append,length方法很方便的解决字符串问题 /* * 剑指offer 替换空格 * xsf * */ /*开始替换空格的函数,length为原数 ...

  9. 剑指Offer面试题39(Java版):二叉树的深度

    题目:输入一棵二叉树的根节点,求该数的深度. 从根节点到叶结点依次进过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度. 比如.例如以下图的二叉树的深度为4.由于它从根节点到叶结点的最 ...

  10. 剑指Offer:面试题25——二叉树中和为某一值的路径(java实现)

    问题描述: 输入一棵二叉树和一个整数,打印出二叉树中结点指的和为输入整数的所有路径.从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.二叉树结点的定义如下: public class Tree ...

随机推荐

  1. 除了C语言,C++······竟然还有Z语言?

    只能说自己见识短,头一次听说Z语言.先普及一下吧: Z语言是由牛津大学程序设计研究小组开发的一种形式语言,它是一种以一阶谓词演算为主要理论基础的规约语言,是一种功能性语言.Z语言是将事物的状态和行为用 ...

  2. Week2-作业1:阅读与博客

    Week2-作业1:阅读与博客 第一章 :概论 1. 原文如下: 移山公司程序员阿超的宝贝儿子上了小学二年级,老师让家长每天出30道加减法题目给孩子做.阿超想写一个小程序来做这件事,具体实现可以采用很 ...

  3. 404 Note Found团队-项目UML设计

    目录 团队信息 分工选择 课上分工 课下分工 ToDolist alpha版本要做的事情 燃尽图 UML 用例图 状态图 活动图 类图 部署图 实例图 对象图 时序图 包图 通信图 贡献分评定 课上贡 ...

  4. 关于jsonp知识的理解

    jsonp 之前知道是用来解决ajax跨域的问题,但是其本质的原理,还是不清楚. 所以看了一下. js的script 的src里面的连接是可以跨域的,所以可以通过她来实现跨域资源获取. 但是也需要后端 ...

  5. PAT 甲级 1126 Eulerian Path

    https://pintia.cn/problem-sets/994805342720868352/problems/994805349851185152 In graph theory, an Eu ...

  6. 使用docker部署项目

    一.Dockerfile编写 FROM hub.c.163.com/library/java:8-alpine ADD target/*.jar app.jar EXPOSE 8761 ENTRYPO ...

  7. TortoiseSVN使用svn+ssh协议连接服务器时重复提示输入密码

    当使用svn+ssh协议连接svn服务器时,ssh会提示请求认证,由于不是svn客户端程序来完成ssh的认证,所以不会缓存密码. 而svn客户端通常会建立多个版本库的连接,当密码没有缓存的时候,就会重 ...

  8. Spring Security OAuth 个性化token

    个性化Token 目的 默认通过调用 /oauth/token 返回的报文格式包含以下参数 { "access_token": "e6669cdf-b6cd-43fe-a ...

  9. 【ARC077F】SS

    Description 如果某个串可以由两个一样的串前后连接得到,我们就称之为"偶串".比如说"xyzxyz"和"aaaaaa"是偶串,而& ...

  10. 破解CobaltStrike3.12(转)

      0x00  概述 CobaltStrike是一款内网渗透的商业远控软件,支持自定义脚本扩展,功能非常强大.前段时间Github上有好心人放出了CobaltStrike3.12的试用版,接着Lz1y ...