zoukankan      html  css  js  c++  java
  • 剑指Offer面试题39(Java版):二叉树的深度

    题目:输入一棵二叉树的根节点,求该数的深度。

    从根节点到叶结点依次进过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度。

    比如。例如以下图的二叉树的深度为4。由于它从根节点到叶结点的最长的路径包括4个结点(从根结点1開始,经过2和结点5,终于到达叶结点7)


    我们能够从还有一种角度来理解树的深度。

    假设一棵树仅仅有一个结点,它的深度为1,假设根节点仅仅有左子树而没有右子树,那么树的深度应该是其左子树的深度+1.相同假设根节点仅仅有右子树而没有左子树,那么树的深度应该是其右子树+1.假设既有左子树又有右子树。那概述的深度就是左、右子树的深度的较大值加1.。

    利用这个思路,我们能够用递归来实现代码:

    //普通二叉树求深度
    	public int treeDepth(BinaryTreeNode root){
    		if(root == null)
    			return 0;
    		int nLeft = treeDepth(root.leftNode);
    		int nRight = treeDepth(root.rightNode);
    		return (nLeft > nRight)?

    (nLeft+1):(nRight+1); }

    假设公司对编程能力有较高的要求。面试官可能会追加一个与前面的问题相关但难度较大的问题,比方,应聘者做完上面的问题后,面试官追问:

    题目二:输入一棵二叉树的根节点。推断该树是不是平衡的二叉树。假设某二叉树中随意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

    须要反复遍历结点多次的解法,简单但不足以打动面试官

    有了求二叉树的深度的经验之后再解决问题,我们非常easy就能想到一个思路:在遍历树的每一个结点的时候,调用函数TreeDepth得到它的左右子树的深度。假设每一个结点的左右子树的深度相差不超过1,依照定义它就是一棵平衡的二叉树。

    这样的思路实现的代码例如以下:

    //推断是否是一颗平衡二叉树
    	public boolean isBalanced(BinaryTreeNode root){
    		if(root ==null)
    			return true;
    		int left = treeDepth(root.leftNode);
    		int right = treeDepth(root.rightNode);
    		int diff = left - right;
    		if(diff > 1 || diff <-1)
    			return false;
    		return isBalanced(root.leftNode) && isBalanced(root.rightNode);
    	}
    上面的代码固然简洁,但我们也注意到因为一个结点会被反复遍历多次,这样的思路的时间效率不高。

    比如在函数isBalanced中输入上图中的二叉树,我们将首先推断根节点是不是平衡的。

    此时我们网函数TreeDepth输入左子树的根节点时须要遍历结点4,5。7.接下来推断以结点2为根节点的子树是不是平衡树的时候。仍然会遍历结点4,5,7.毫无疑问,反复遍历同一个结点会影响性能。接下来我们寻找不须要反复遍历的算法。

    每一个结点仅仅遍历一次的解法,正是面试官喜欢的算法

    假设我们用后序遍历的方式遍历二叉树的每一个结点。在遍历一个结点之前我们就已经遍历了它的左右子树。仅仅要在遍历每一个结点的时候我们记录它的深度(某一节点的深度等于它到叶结点的路径的长度),我们就能够一边遍历一边推断每一个结点是不是平衡二叉树。

    以下是这样的思路的实现代码:

    //高效率的推断是否是一棵平衡二叉树
    	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;
    	}

    在上面的代码中,我们用后序遍历的方式遍历整棵二叉树。在遍历某结点的左右子树结点之后,我们就能够依据它的左右子树的深度推断它时不时平衡的,并得到当前结点的深度。当最后遍历到树的根节点的时候,也就推断了整棵二叉树是不是平衡二叉树。


  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7103119.html
Copyright © 2011-2022 走看看