标签:
https://oj.leetcode.com/problems/balanced-binary-tree/
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
解题思路:
这题的解法也比较straightforward,题目的说明已经明显给出了这是一个递归的问题。一个数是平衡的,当且仅当它的每个节点是平衡的,并且它们的左右子树也是平衡的。平衡的定义就是,左右子树的高度差不超过1。
求深度的方法很简单,前面已经做过,本身就是一个递归的方法。那么对于isBalanced()这个方法,只需递归求出每个节点的左右子树高度差是不是>1,如果>1直接返回false。否则,继续看左右子树是不是平衡的,即isBalanced(root.left) && isBalanced(root.right)。
递归结束的条件是,当前节点为null,返回true。代码如下。
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public boolean isBalanced(TreeNode root) { if(root == null){ return true; } if(getDepth(root.left) - getDepth(root.right) > 1 || getDepth(root.left) - getDepth(root.right) < -1){ return false; }else{ //这个地方一开始写错了,导致一直找不到递归的入口 return isBalanced(root.left) && isBalanced(root.right); } } public int getDepth(TreeNode root){ if(root == null){ return 0; } int leftDepth = getDepth(root.left); int rightDepth = getDepth(root.right); return Math.max(leftDepth, rightDepth) + 1; } }
但是这里我们可以看到,本身isBalanced()的方法就是递归的,里面又有一个递归的getDepth()方法,时间复杂度为O(n^2)(是不是?我也不太清楚……)。
考虑简化。思考一下,getDepth()这个方法其实每个节点都要向下算一次,重复了很多遍。想象动态规划问题的解法,用一个大小为n的数组记录所有节点的深度,在isBanlanced()方法开始的时候仅算一次,不就可以了吗?这里用数组记录,后面取值的时候不是很方便,无法有效准确的获取每个node的index。所有考虑用一个hashmap来存。
要注意的是,如果左子树或者右子树为空,depth == 0,这时调用map.get()的方法是会出错的。代码如下。
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { Map<TreeNode, Integer> depthMap = new HashMap<TreeNode, Integer>(); public boolean isBalanced(TreeNode root) { if(root == null){ return true; } //一次性算出所有节点的depth initDepth(root); int leftDepth = 0; int rightDepth = 0; //如果left为null,深度就为0了,否则取得left的深度 if(root.left != null){ leftDepth = depthMap.get(root.left); } if(root.right != null){ rightDepth = depthMap.get(root.right); } if(leftDepth - rightDepth > 1 || leftDepth - rightDepth < -1){ return false; }else{ return isBalanced(root.left) && isBalanced(root.right); } } //一个预先初始化所有节点depth的方法,存入当前节点的val中,避免后面再次递归求depth public int initDepth(TreeNode root){ if(root == null){ return 0; } int leftDepth = initDepth(root.left); int rightDepth = initDepth(root.right); depthMap.put(root, Math.max(leftDepth, rightDepth) + 1); return Math.max(leftDepth, rightDepth) + 1; } }
更一般的,我们还可以借助每个node的val字段,直接把它的depth存在里面,就可以省去这个n个空间的map了。
同样,如果左子树或者右子树为空,depth == 0,否则这时调用root.left.val是会出错的。
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public boolean isBalanced(TreeNode root) { if(root == null){ return true; } //一次性算出所有节点的depth initDepth(root); int leftDepth = 0; int rightDepth = 0; //如果left为null,深度就为0了,否则取得left的深度 if(root.left != null){ leftDepth = root.left.val; } if(root.right != null){ rightDepth = root.right.val; } if(leftDepth - rightDepth > 1 || leftDepth - rightDepth < -1){ return false; }else{ return isBalanced(root.left) && isBalanced(root.right); } } //一个预先初始化所有节点depth的方法,存入当前节点的val中,避免后面再次递归求depth public int initDepth(TreeNode root){ if(root == null){ return 0; } int leftDepth = initDepth(root.left); int rightDepth = initDepth(root.right); root.val = Math.max(leftDepth, rightDepth) + 1; return root.val; } }
标签:
原文地址:http://www.cnblogs.com/NickyYe/p/4298785.html