我已经非常善于计算时间复杂度,但我仍然对如何确定指数时间算法感到困惑。下面的算法具有最差情况下的运行时间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)
}
答案 0 :(得分:2)
您提供的算法的复杂性不是O(k^n)
。复杂性只是O(nk)
。该算法评估 nk 。
答案 1 :(得分:2)
O(k^n)
对我来说似乎是正确的。
j-
和q-loop
共有k * power
次迭代。但power
每次i-loop
次迭代都会按指数级更新。
i=1
,j-
和q-loop
进行k * 1
次迭代时。i=2
,j-
和q-loop
进行k * k
次迭代时。 i=3
,j-
和q-loop
进行k * (k*k)
次迭代时。 i=m
,j-
和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
:
power
添加到newpower
k
次,因此此计算k * power
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)。