棘手的时间复杂性

时间:2014-08-06 04:21:47

标签: algorithm time-complexity

我已经非常善于计算时间复杂度,但我仍然对如何确定指数时间算法感到困惑。下面的算法具有最差情况下的运行时间O(k ^ n)。他们是如何获得这个价值的?第一个for循环占用 n 时间,第二个for循环占用 k 时间,而第三个for循环 q 时间令人困惑。如果运行时间 n * k * q -something,他们是如何获得O(k ^ n)的?

int exp(k, n) {
    power = 1
    for i = 1 to n {
        newpower = 0
        for j = 1 to k {
            for q = 1 to power {
                newpower++
            }  
        }
        power = newpower
    }
    return (power)
}

5 个答案:

答案 0 :(得分:2)

您提供的算法的复杂性不是O(k^n)。复杂性只是O(nk)。该算法评估 nk

答案 1 :(得分:2)

O(k^n)对我来说似乎是正确的。

j-q-loop共有k * power次迭代。但power每次i-loop次迭代都会按指数级更新。

  • i=1j-q-loop进行k * 1次迭代时。
  • i=2j-q-loop进行k * k次迭代时。
  • i=3j-q-loop进行k * (k*k)次迭代时。
  • i=mj-q-loop进行k * (k^(m-1))次迭代时。

k*(k^(m-1))只是k^m,其中1 <= m <= n。因此,对于n次迭代,所有迭代的总和是渐近O(k^n)

答案 2 :(得分:1)

在第三个循环出现后,O(k^n)的复杂性才有意义。

首先,你必须看到算法计算k^n

  • q-loop将当前power添加到newpower
  • k循环运行q循环k次,因此此计算k * power
  • 这是i-loop
  • 执行n

所以你得到k* .... k*(k*(k*1)) (n-times) = k^n

现在我们知道算法计算k^n并且只通过添加1来执行此操作,因此他需要添加k^n 1,因此复杂度为{{1}确切地说(Θ(k ^ n))

答案 3 :(得分:0)

       for q = 1 to power {
            newpower++
       }  

可以缩减为

       newpower += power;

这个

    newpower = 0
    for j = 1 to k {
        for q = 1 to power {
            newpower++
        }  
    }
    power = newpower

   power *= k;

因此它实际上通过反复递增来计算k^n。这是O(k^n)

答案 4 :(得分:0)

要解决这些棘手的问题,你必须仔细计算正在执行的指令数量,这并不总是很容易(可能需要更高级别的数学运算)。

在这个问题中,让我们尝试计算newpower ++发生的次数(即最内层循环中的循环次数),然后让我们以k循环的块来查看它。在第一次运行中,每个运行k个块为1个运行:

1 1 1 1 ...
=循环1 * k次= k次

然后power = k。然后我们有k块k: k k k k ...
=循环k * k次= k ^ 2次

继续这种模式,你会看到newpower ++执行的次数是:
k + k ^ 2 + k ^ 3 + ... k ^ n次。

然而,k ^ n项占据了其余部分,所以你留下了O(k ^ n)。