【问题标题】:Time complexity of divide and conquer relation分治关系的时间复杂度
【发布时间】:2019-02-08 21:26:51
【问题描述】:

我正在尝试两个计算以下函数的时间复杂度。 我尝试了两种不同的方法

1) 因为几乎每次都会有两个递归调用。 我们可以将递归关系写为T(n)=2T(n/2)+c。 这给了我们O(logn)

2)但我们也可以说递归调用的总数将是 等于 n,这使我们的时间复杂度为O(n)。 因为每次数字都减半,但有两个递归调用。

哪一个是正确的?

我从这里看到了第二种方法https://www.geeksforgeeks.org/write-a-c-program-to-calculate-powxn/

在上面的链接中查看方法1的时间复杂度

注意->我知道我们可以存储 power(x,n/2) 的结果。

/* Function to calculate x raised to the power n */

int power(int x, unsigned int n) 
{ 
    if (n == 0) 
        return 1; 
    else if (n%2 == 0) 
        return power(x, n/2)*power(x, n/2); 
    else
        return x*power(x, n/2)*power(x, n/2); 
} 

【问题讨论】:

    标签: algorithm time-complexity


    【解决方案1】:

    1) 因为几乎每次都会有两个递归调用。 我们可以将递归关系写为T(n)=2T(n/2)+c。 这给了我们O(logn)

    不知何故,你在这里犯了一个错误。 T(n) = 2‍T(n/2) + c 确实O(log n);相反,它给出了 O(n)。 (这属于案例 1,https://en.wikipedia.org/wiki/Master_theorem_(analysis_of_algorithms)。)

    2)但我们也可以说递归调用的总数将是 等于 n 这使我们的时间复杂度为O(n)。 因为每次数字都减半,但有两个递归调用。

    这是正确的。

    【讨论】:

    • @kjsir121 - wiki 上没有 master 方法的证明,如果您对证明感兴趣,probalby this doc 可能会很有用。
    【解决方案2】:

    所以T(n)=2T(n/2)+c 这实际上是 O(n) 本身。

    这是对此的正式证明。 T(n)=2T(n/2^1 )+c(2^0)

    更进一步

    T(n)=2(2T(n/2^2 )+c)+c(2^0 )

    简化:

    T(n)=2^2 T(n/2^2 )+c(2^0 )+c(2^1 )

    如果你进一步打破它,你可以尝试一下,你会得到这样的表达

    T(n)=2^3 T(n/2^3 )+c(2^0 )+c(2^1 )+c(2^2)

    现在关键是你能把它打破多远,应该是当 2^something 等于 n 时,n/n=1 并且 T(1) 是常数。

    这个东西可以很容易地计算为 log(n)base(2)。

    所以通过检查你可以预测你的最终表达式会是这样的,

    T(n)=2^log(n) T(n/2^log(n))+c(2^0)+c(2^1)+........+2 ^(log(n)-1)

    =n T(1)+c(2^0+2^1+2^2+.......2^(log(n)-1))
    
    =n T(1)+c(n-1)
    

    因此,

    T(n)= (T(1)+c)n-c 即 o(n)。

    【讨论】:

      猜你喜欢
      • 2016-02-06
      • 2015-07-07
      • 2021-11-30
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      相关资源
      最近更新 更多