简体   繁体   English

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

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

This is from problem 4.8 of Cracking the Coding Interview 6th edition.这是来自 Cracking the Coding Interview 6th edition 的问题 4.8。 The following code is one solution to the following prompt: "Find the first common ancestor of two nodes in a binary tree"以下代码是以下提示的一种解决方案:“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;

}

The book says that "this algorithm takes O(t) time, where t is the size of the subtree for the first common ancestor. In the worst case this will be O(n)"这本书说“这个算法需要 O(t) 时间,其中 t 是第一个共同祖先的子树的大小。在最坏的情况下,这将是 O(n)”

However, aren't the calls to covers from root at the beginning of commonAncestor making the runtime O(d+t), d being the depth of the either p or q, depending on which one is deeper.然而,在 commonAncestor 开始时从根调用covers 不是使运行时O(d+t),d 是p 或q 的深度,这取决于哪个更深。

Well, it looks like cover(root,p) will search the entire sub-tree rooted at x , since it checks both root.left and root.right recursively.好吧,看起来cover(root,p)将搜索以x为根的整个子树,因为它递归地检查root.leftroot.right

But yes, this problem can be solved in time O(d).但是是的,这个问题可以在 O(d) 时间内解决。 (Go up from each of p , q to the root, and then just the first element the two lists have in common.) (从pq中的每一个上升到根,然后只是两个列表共有的第一个元素。)

Um, it looks like that code inside cover is wrong, too, in a couple different ways:嗯,看起来cover里面的代码也是错误的,有几种不同的方式:

  • it presumably wants to return false rather than return null when we've recurred "off the end" of a branch;当我们在分支的“末尾”重复出现时,它可能想要return false而不是return null
  • even more troublesome, it should check that occasionally it has found the target: if (root==p) return true .更麻烦的是,它应该偶尔检查是否找到了目标: if (root==p) return true (One could be clever and modify the existing return statement to be return (root==p) || covers(..,..) || covers(..,..) .) (可以聪明地将现有的return语句修改为return (root==p) || covers(..,..) || covers(..,..) 。)

You may want to review the part on Big O in the beginning of the book.您可能需要查看本书开头的 Big O 部分。 O(d+t) is somewhat accurate, but because that's a plus one of them (either d or t) is going to get bigger faster than the other. O(d+t) 有点准确,但因为这是一个加号,其中一个(d 或 t)会比另一个更快地变大。 In this case, t = # of nodes in a subtree, and d = depth in the overall tree.在这种情况下,t = 子树中的节点数,d = 整个树中的深度。 T is going to grow significantly faster than d. T 将比 d 增长得更快。

As an illustration:举例说明:

      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

Due to the way trees work depth will always be equal to or smaller than the number of nodes.由于树的工作方式,深度将始终等于或小于节点数。 Therefore the time complexity will be average (big theta?) of t (# of nodes in subtree) and at worst (big o) n (#number of nodes in tree).因此,时间复杂度将是 t(子树中的节点数)的平均值(大 theta?),最坏的情况是(大 o)n(树中的节点数)。

As an aside, the checks to root are going to do O(n) at the start which would make the whole thing O(n), but the author states that it does, in fact have O(n).顺便说一句,对 root 的检查将在开始时执行 O(n),这将使整个事情 O(n),但作者指出它确实如此,实际上有 O(n)。 "this algorithm takes O(t) time" is, I think, the author's analysis for average case. “这个算法需要 O(t) 时间”是,我认为,作者对平均情况的分析。

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

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