题目
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回true。
思路一——暴力
通过调用函数分别求解左右子树的最大深度,然后求解其高度绝对差值,如果不满足条件,返回false;否则当栈空时,返回true。递归调用函数求解最大深度时时间复杂度为O(logN),同时外层要遍历二叉树,因此总体时间复杂度为O(NlogN)。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode temp = stack.pop();
int len1 = maxDepth(temp.left);
int len2 = maxDepth(temp.right);
if(Math.abs(len1 - len2) > 1)return false;
if(temp.left != null)stack.push(temp.left);
if(temp.right != null)stack.push(temp.right);
}
return true;
}
//求解最大深度
public int maxDepth(TreeNode root){
if(root == null) return 0;
int min1 = maxDepth(root.left);
int min2 = maxDepth(root.right);
return Math.max(min1, min2) + 1;
}
}
简化代码:
由于该代码不需要入栈出栈操作,运行时间提高了。
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
return Math.abs(maxDepth(root.right) - maxDepth(root.left)) < 2 && isBalanced(root.left) && isBalanced(root.right);
}
//求解最大深度
public int maxDepth(TreeNode root){
if(root == null) return 0;
int min1 = maxDepth(root.left);
int min2 = maxDepth(root.right);
return Math.max(min1, min2) + 1;
}
}
思路二
由于思路一中在反复调用求解高度,以及判断左右子树是否为平衡子树,存在大量冗余。可以采用自底向上的方法,即先序遍历,如果左子树不是平衡二叉树,返回-1,如果右子不是平衡二叉树,返回-1,不需要计算其他的子树是否为平衡二叉树;否则判断该结点是否为平衡二叉树,如果不是返回-1 ,否则返回该结点的最大深度。根据返回值判断是否为平衡二叉树,如果为-1,则返回false,否则返回true。
class Solution {
public boolean isBalanced(TreeNode root) {
return recur(root) != -1;
}
//递归求解是否为平衡二叉树,否返回-1,自底向上,提前阻断
public int recur(TreeNode root){
if(root == null) return 0;
int min1 = recur(root.left);
if(min1 == -1) return -1;
int min2 = recur(root.right);
if(min2 == -1) return -1;
return Math.abs(min1 - min2) < 2 ? Math.max(min1 , min2) + 1 : -1;
}
}