【问题标题】:How does this algorithm have complexity of O(n^2)?该算法的复杂度如何为 O(n^2)?
【发布时间】:2023-03-16 20:48:01
【问题描述】:

设v为树T的一个节点。节点v的深度可以定义如下:

  • 如果 v 是根,则 v 的深度为 1。
  • 否则,v 的深度是 1 加上 v 的父级的深度。

基于上述定义,递归算法深度,如下面的算法所示,通过在 v 的父节点上递归调用自身,并将返回的值加 1 来计算 Tree 的节点 v 的深度。

算法depth(T, y):

  • 第一步:如果T.isRoot(v),则返回1
  • 第2步:否则,返回1 + depth(T, T. parent(v))

一棵树 T 的高度等于 T 的外部节点的最大深度。虽然这个定义是正确的,但它不会导致一个有效的算法。事实上,如果我们将上述深度查找算法应用于树 T 中的每个节点,我们将推导出一个 O(n2) 时间的算法来计算 T 的高度。

根据上面的说法怎么可能是O(n2)?如果我们在每个外部节点上尝试这个算法,那么它需要 O(n),并且找到最大值需要 O(n)。所以总复杂度应该是O(n)+O(n) = O(2n)==O(n)吧?

【问题讨论】:

    标签: algorithm data-structures


    【解决方案1】:

    算法的最坏情况是不平衡的树。例如如下图所示的一棵树:

    上面的树有 5 个外部节点和 5 个内部节点,所以正好有一半的节点是外部节点。从 A 开始,有一个父级。从B开始,有2个,以此类推。所以访问的父母(P)总数为1+2+3+...+(n/2)

    使用formula for the sum of natural numbers 我们有P = (n/2)(n/2 + 1)/2 = (n^2 + 2n)/8。忽略常数因子 (8) 和次要项 (2n),我们看到 P 为 O(n^2)。

    【讨论】:

      【解决方案2】:

      如果我们在每个外部节点上都尝试这个算法,那么它需要 O(n)

      这是不正确的。您将应用算法n 次,其中每个调用需要O(n) 时间,这导致总共O(n^2) 时间。

      这当然是假设没有缓存/记忆结果(所以我们做了很多重复的工作)。如果有,那确实是O(n)

      【讨论】:

      • 如果你应用memoization,那么你必须考虑你不能直接说它是O(n)的边数。相反,它应该是 O(n+E),因为我们不知道 n 和 E 中的哪一个占主导地位,因为它们都是 1 次方。
      • 它是一棵树,所以根据定义它有N-1条边@Mateen
      • 啊!是的!但对于算法的泛化仍然适用。
      【解决方案3】:

      在渐近符号中,n^2 可能意味着,对于每个节点,您访问的节点数量可变,最大 nn - 1。 让我们考虑一下:

      当你为节点1调用递归函数时,它立即返回,但是当你为节点5调用它时,你需要重新计算所有节点的深度直到node 1,这意味着您访问了所有其他节点,因为您没有使用 memoization。因此,对于您正在访问 [1 到 n-1] 个节点的每个节点。

      【讨论】:

        猜你喜欢
        • 2019-12-13
        • 2011-06-05
        • 2021-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-12
        • 2019-12-09
        • 2015-05-25
        相关资源
        最近更新 更多