110. 平衡二叉树
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/balanced-binary-tree/
题目描述见链接内容。
分析
二叉树我总是搞不太明白,这道题又卡住了,没信心了
需要用到递归的方式判断,因为一颗二叉树是平衡树,那它的子树也都是平衡树
解法1:自顶向下
前几天刚刚学习过,如果求一个二叉树的最大深度:
function getHeight(node) {
if (!node) {
return 0;
}
return Math.max(getHeight(node.left), getHeight(node.right)) + 1;
}
然后自顶向下的去遍历这棵树,实际上就是前序遍历,按照根 → 左 → 右
的顺序去遍历:对于当前的节点,计算左右子树的高度,如果高度差不超过1
,再分别递归地遍历左右子树
var isBalanced = function (root) {
if (!root) {
return true;
}
return Math.abs(getHeight(root.left) - getHeight(root.right)) < 2 && isBalanced(root.left) && isBalanced(root.right);
};
- 时间复杂度:最坏情况
${O(n^2)}$
,平均情况${O(nlog n)}$
,其中n
为二叉树中节点的个数 - 空间复杂度:
${O(n)}$
,其中n
为二叉树中节点的个数 - 执行用时:104ms,在所有JavaScript提交中击败了56%的用户,内存消耗:41.8MB,在所有JavaScript提交中击败了95%的用户
解法2
上面的解法,对于一个节点,getHeight
方法会被反复调用,导致时间复杂度比较高。如果使用自底向上的方法,即使用后续遍历,按照左 → 右 → 根
的顺序去遍历,那么一个节点只会调用一次getHeight
方法
对于当前遍历到的节点,先递归的判断其左右子树是否平衡,再判断以当前节点为根的子树是否平衡,如果一颗子树是平衡的,返回其高度,如果是不平衡的则返回-1
var isBalanced = function (root) {
return getHeight(root) > -1;
};
function getHeight(node) {
if (!node) {
return 0;
}
const leftHeight = getHeight(node.left);
if (leftHeight === -1) {
return -1;
}
const rightHeight = getHeight(node.right);
if (rightHeight === -1 || Math.abs(leftHeight - rightHeight) < 2) {
return -1;
}
return Math.max(leftHeight, rightHeight) + 1;
}
- 时间复杂度:
${O(n)}$
,其中n
为二叉树中节点的个数 - 空间复杂度:
${O(n)}$
,其中n
为二叉树中节点的个数 - 执行用时:88ms,在所有JavaScript提交中击败了98%的用户,内存消耗:42.1MB,在所有JavaScript提交中击败了61%的用户