二叉树平衡的定义:
一般的一颗二叉树是平衡的,当且仅当 左右两颗子树的高度差的绝对值不超过 1 ,并且左右两颗子树都是一颗平衡二叉树。特别的,空树也是一颗平衡二叉树。 树结点定义:class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val){
this.val=val;
}
}
解法一:计算左右子树的高度差绝对值是否小于等于1
先求树的高度,采用递归算法。 请记住关于树形结构递归算法的出口为: 结点为空
int getTreeHeight(TreeNode root){
//结点为空,返回树的高度为0
if(root==null)return 0;
//计算左子树的高度
int leftHeight=getTreeHeight(root.left);
//计算右子树的高度
int rightHeight=getTreeHeight(root.right);
//返回树的高度为左右子树中较大的值+1
return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
}
从根结点开始,依次计算每个结点的左右子树的高度
Boolean isBalance(TreeNode root){
if(root==null)return true; //结点为空,返回true
int value= getTreeHeight(root.left)-getTreeHeight(root.right);
return
Math.abs(value)<=1&&isBalance(root.left)&&isBalance(root.right);
//计算root结点的左右子树的高度差,并且判断左右子树是否平衡
}
解法一复杂度分析:虽然 isBalance函数对于每个结点只运行一次。然而,getHeight函数会对每一个结点的所有子结点进行计算,重复计算了很多子孙结点。 时间复杂度O(N^2),空间复杂度O(N)。
解法二(最优解): 后序遍历,判断一个结点是否平衡,先得到他的左右子树的高度。如果树子树的高度差大于1,则该结点的高度定义为-1
public boolean isBalanced(TreeNode root) {
if(root==null) return true;
return height(root)!=-1;
}
public int height(TreeNode node){
if(node==null) return 0;
int lH=height(node.left);
if(lH==-1)return -1;
int rH=height(node.right);
if(rH==-1)return -1;
if(lH-rH<-1 || lH-rH>1) return -1;
return Math.max(lH,rH)+1;
}
时间复杂度为O(N),空间复杂度O(N)。
参考文献:
1.leetcode https://leetcode.com/problems/balanced-binary-tree/#/description
2.左程云. 程序员代码面试指南-IT名企算法与数据结构题目最优解.电子工业出版社