原题目
面试题 04.04. 检查平衡性
实现一个函数,检查二叉树是否平衡。在这个问题中,平衡树的定义如下:任意一个节点,其两棵子树的高度差不超过 1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回 false 。
第一遍解法
(废话,大家可忽略)最开始打算使用BFS的思路来做,最后发现BFS只能知道每层节点的高度,如果只判断根节点左子树高度与右子树高度之差是不行的,因为可能根节点下的某个子树自身不平衡而根节点左右子树高度差小于等于1的情况。
DFS,既然直接判断大树是否平衡是不行的,可以分治,如果左树和右树都是平衡的,且高度之差小于等于1,那么就认为该树是平衡的。
class Solution {
public boolean isBalanced(TreeNode root) {
return isTreeBalanced(root) != -1 ? true : false;
}
private int isTreeBalanced(TreeNode node) {
if (node == null) {
return 0;
}
int leftHigh = isTreeBalanced(node.left);
int rightHigh = isTreeBalanced(node.right);
if (leftHigh == -1 || rightHigh == -1) {
return -1; // -1表示不平衡
}
if (Math.abs(leftHigh - rightHigh) > 1) {
return -1;
}
return leftHigh > rightHigh ? leftHigh + 1 : rightHigh + 1;
}
}
时间复杂度: O(n)
- 迭代法,1+2+…+2^log(n) --> 2n - 1
空间复杂度: O(n)
- 递归栈,最坏的情况下为n / 2
网上的解法
也是DFS思想。
class Solution {
private boolean balanced = true; // 默认是平衡的
public boolean isBalanced(TreeNode root) {
treeDepth(root);
return balanced;
}
/*
使用DFS计算以root为根的树的高度
DFS的优点是最多访问所有节点一次
先判断子树的平衡性,如果子树不平衡则说明整棵树是不平衡的,提前终止遍历
*/
public int treeDepth(TreeNode root) {
// 空树的高度为0
// !balanced返回0完全是为了终止递归,其实返回什么无所谓
if (root == null || !balanced) {
return 0;
}
int leftTreeDepth = treeDepth(root.left); // 左子树高度
int rightTreeDepth = treeDepth(root.right); // 右子树高度
// 平衡性判断
if (Math.abs(leftTreeDepth - rightTreeDepth) > 1) {
balanced = false;
}
// root树的高度应该是左右子树较大者 + 1
return Math.max(leftTreeDepth, rightTreeDepth) + 1;
}
}
作者:zui-weng-jiu-xian
链接:https://leetcode-cn.com/problems/check-balance-lcci/solution/xin-shou-di-gui-jie-fa-by-zui-weng-jiu-xian/
来源:力扣(LeetCode)
时间复杂度: O(n)
空间复杂度: O(n)
最后的代码
结合网上代码形式,简洁了下自己代码的判断条件。但发现与网上代码基本一致了,想了好一会都不知道还应该如何简洁。
class Solution {
private boolean balanced = true;
public boolean isBalanced(TreeNode root) {
treeDepth(root);
return balanced;
}
private int treeDepth(TreeNode node) {
if (node == null || !balanced) {
return 0;
}
int leftHigh = treeDepth(node.left);
int rightHigh = treeDepth(node.right);
if (Math.abs(leftHigh - rightHigh) > 1) {
balanced = false;
}
return Math.max(leftHigh, rightHigh) + 1;
}
}
小结
-
Math.abs求绝对值,Math.max求最大值,Math.min求最小值。
-
遇到树的问题应当与遇到图的问题一样,先在脑海中过一遍DFS或者BFS能不能解决。