盖尔·拉克曼·麦克道威尔(Gayle Laakmann McDowell)提出的破解编码面试的提示:
实现一个功能来检查二叉树是否平衡。 对于此问题,定义了一个平衡树,使得高度 任何节点的两个子树中的一个的相差不超过一个。
(以下示例实现。)
问题:您能帮助我理解为什么作者指出isBalanced
有一个
O(n log n)
的时间复杂度?我在某种程度上可以记住它,但是可以记住,但是我无法概念化为什么像O(n^2)
这样的其他时间复杂性,为什么会出现这种情况。
int getHeight(TreeNode root) {
if (root == null) { return -1; }
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
boolean isBalanced(TreeNode root) {
if (root == null) { return true; }
int heightDiff = getHeight(root.left) - getHeight(root.right);
if (Maths.abs(heightDiff) > 1) {
return false;
} else {
return isBalanced(root.left) && isBalanced(root.right);
}
}
// isBalanced([some node]) --> true/false
我如何可视化为什么将isBalanced
视为O(n log n)
?
答案 0 :(得分:3)
假设您有BST
4 // No of nodes 1
/ \
2 6 // No of nodes 2
/ \ / \
1 3 5 7 // No of nodes 4
您的函数isBalanced
将遍历所有节点,包括没有子节点的节点,并调用getHeight
以计算左右子节点的高度。
该函数的递归关系为
这是从“主定理”中得出的
a
=递归子问题的数量
n/b
=每个子问题的大小
f(n)
=必须在递归调用之外完成的工作成本
a
是2
,因为我们必须访问每个父节点的两个子节点
b
是2
,因为如果您注意到每次到达(从底部)上方的水平,节点数都会减少一半。
f(n)
是n
,因为我们必须在每个节点上调用getHeight()
满足主定理的第二种情况
输入值以证明f(n) = O(n^logb(a))
因此,我们得到了O(n log n)
的时间复杂度