此问题取自LeetCode的“最大二叉树深度”:
Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
嗯,递归方法非常简单:
public int maxDepth (TreeNode root) {
if(root == null)
return 0;
return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}
我无法弄清楚这个解决方案的时间复杂性。有人说这是O(n)
。同时不计算maxDepth(root.left)
和maxDepth(root.right)
,这会使时间复杂度O(lg(n))
?
答案 0 :(得分:7)
maxDepth(root.left)和maxDepth(root.right)只有在并行运行时才能同时计算,如果是,则复杂性取决于可以并行运行的可用处理器数量。也就是说,你的Java代码没有并行运行任何东西,因为它们都运行在同一个线程上。
假设顺序执行,maxDepth
必须遍历整个树,因为它不知道某个路径是否可以导致最大深度,直到它到达结束该路径的叶子。因此,时间复杂度为O(n)。
答案 1 :(得分:3)
根据Java规范,函数的最左边的参数首先被完全评估,然后是正确的参数。它们不是在算法上同时计算的,并且它们不是按时间顺序在不同的线程/核心上同时执行。
以这种方式思考:算法将通过每个节点一次。这意味着算法为O(n)
。
如果你不相信,你可以使用Master Theorem(在维基百科的表示法中)以较不全面的方式得出相同的结论:
对于大小为N的树,我们在树的一半上进行两次调用,加上我们对该节点的常量工作(检查null并添加1):
T(n) = 2 * T(n/2) + 1
^-a ^-b ^-f(n)
该定理有多个案例,并说案例1涵盖了f(n)
为O(n^c)
的算法,其中c < log_b(a)
如上所述。我们的f(n)
为O(n^0)
(常数)和log_b(a) = log2(2) = 1
。该定理然后声明运行时是:
T(n) = Θ(n^log_b(a))
对我们来说意味着
T(n) = Θ(n^1) = Θ(n)
这是达到相同答案的通用但更长的方法。