我有这个算法,我无法弄清楚它的时间复杂度是多少。
int oc(int n) {
if (n == 0)
{
return 0;
}
int s = p[n][0];
for (int i = n-1; i > 0; i--)
{
int a = p[n][i] + oc(i);
if (s > a)
{
s = a;
}
}
return s;
}
我假设for-loop上有(n-1)次迭代,但可以计算出使用递归时的总运行时间。
答案 0 :(得分:1)
让T(n)
是计算oc(n)
的复杂性。因为对于计算oc(n)
,您正在运行从n-1
到1
的循环并递归调用oc(i)
,因此
T(n)=T(n-1)+T(n-2)+...+T(1) (*).
如果不是T(n-1),我们就把
T(n-1)=T(n-2)+T(n-3)+...+T(1)
在(*)
平等中,我们将得到:
T(n)=2*(T(n-2)+...+T(1))
如果我们继续对T(n-2)
,T(n-3)
等进行相同的迭代,我们将在平等后得出结论:
T(n)=2*(T(n-2)+...+T(1))
=4*(T(n-3)+...+T(1))
=2^i*(T(n-i-1)+...+T(1))
=2^n*T(1)/2=O(2^n).
这种复杂性的原因是 - 你的算法多次计算同样的事情。
如果你在数组中记住你已经计算了oc函数值的值,并在函数的第一部分添加一个检查,它将直接从数组返回值(如果已经计算了)而不是运行循环并再次执行相同的操作作业,算法的复杂性将发生巨大变化,并且将为O(n)
,因为算法将在进行循环的第一次迭代时计算所有值并存储。
答案 1 :(得分:0)
O(2 n )。了解增加 n 的迭代次数:
n | f(n) = total iterations
---+-------------------------------------------------
1 | 0
2 | 1 + f(1) = 1 + 0 = 1
3 | 2 + f(2) + f(1) = 1 + 2f(2) = 1 + 2.1 = 3
4 | 3 + f(3) + f(2) + f(1) = 1 + 2f(3) = 1 + 2.3 = 7
...| ...
n | .... 1 + 2.f(n-1) = 2^(n-1) - 1