繁体   English   中英

为什么这个算法的运行时间是 O(t)?

[英]Why is the runtime of this algorithm O(t)?

这是来自 Cracking the Coding Interview 6th edition 的问题 4.8。 以下代码是以下提示的一种解决方案:“Find the first commonance of two nodes in a binary tree”

TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q){
/* Checks if either node is not in the tree, or if one covers the other. */
   if(!covers(root, p) || !covers(root, q)){
      return null;
   } else if (covers(p,q)){
      return p;
   } else if (cover(q,p)){
      return q;
   }

   /* Traverse upwards until you find a node that covers q. */
   TreeNode sibling = getSibling(p);
   TreeNode parent = p.parent;
   while(!covers(sibling, q)){
    sibling = getSibling(parent);
    parent = parent.parent;
   }

   return parent;
}

boolean covers(TreeNode root, TreeNode p){
   if(node == null) return false;
   if(root == p) return true;
   return covers(root.left, p) || covers(root.right,p);
}

TreeNode getSibling(TreeNode node){
   if(node == null || node.parent ==null){
     return null;
   }

   TreeNode parent = node.parent;
   return parent.left == node ? parent.right: parent.left;

}

这本书说“这个算法需要 O(t) 时间,其中 t 是第一个共同祖先的子树的大小。在最坏的情况下,这将是 O(n)”

然而,在 commonAncestor 开始时从根调用covers 不是使运行时O(d+t),d 是p 或q 的深度,这取决于哪个更深。

好吧,看起来cover(root,p)将搜索以x为根的整个子树,因为它递归地检查root.leftroot.right

但是是的,这个问题可以在 O(d) 时间内解决。 (从pq中的每一个上升到根,然后只是两个列表共有的第一个元素。)

嗯,看起来cover里面的代码也是错误的,有几种不同的方式:

  • 当我们在分支的“末尾”重复出现时,它可能想要return false而不是return null
  • 更麻烦的是,它应该偶尔检查是否找到了目标: if (root==p) return true (可以聪明地将现有的return语句修改为return (root==p) || covers(..,..) || covers(..,..) 。)

您可能需要查看本书开头的 Big O 部分。 O(d+t) 有点准确,但因为这是一个加号,其中一个(d 或 t)会比另一个更快地变大。 在这种情况下,t = 子树中的节点数,d = 整个树中的深度。 T 将比 d 增长得更快。

举例说明:

      1
    /   \
  2       3
 / \     / \
4   5   6   7

If We're looking at this tree and we want to know the common ancestor for 4 and 5:
  t = 3
  d = 3
if we want the common ancestor of 2 and 7 in the same tree then:
  t = 7
  d = 3

由于树的工作方式,深度将始终等于或小于节点数。 因此,时间复杂度将是 t(子树中的节点数)的平均值(大 theta?),最坏的情况是(大 o)n(树中的节点数)。

顺便说一句,对 root 的检查将在开始时执行 O(n),这将使整个事情 O(n),但作者指出它确实如此,实际上有 O(n)。 “这个算法需要 O(t) 时间”是,我认为,作者对平均情况的分析。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM