我需要为以下算法构建递归关系(T(n)代表元素动作的数量)并找到它的时间复杂度:
Alg (n)
{
if (n < 3) return;
for i=1 to n
{
for j=i to 2i
{
for k=j-i to j-i+100
write (i, j, k);
}
}
for i=1 to 7
Alg(n-2);
}
我来到这个递归关系(不知道它是否正确):
如果n <1,则T(n)= 1。 3
T(n)= 7T(n-2)+ 100n 2 否则。
但我不知道如何获得时间复杂度。
我的复发是否正确?这段代码的时间复杂度是多少?
答案 0 :(得分:0)
让我们看看代码,看看复发应该是什么。
首先,让我们看一下循环:
for i=1 to n
{
for j=i to 2i
{
for k=j-i to j-i+100
write (i, j, k);
}
}
这需要做多少工作?好吧,让我们从简化它开始吧。我们不是将j
从i
计算到2i
,而是定义一个从j'
到0
计数的新变量i
。这意味着j'
= j - i
,因此我们得到了这个:
for i=1 to n
{
for j' = 0 to i
{
for k=j' to j'+100
write (i, j' + i, k);
}
}
啊,那好多了!现在,我们也将k
重写为k'
,其中k'
的范围是1到100:
for i=1 to n
{
for j' = 0 to i
{
for k'= 1 to 100
write (i, j' + i, k' + j);
}
}
由此可以更容易地看出这个循环具有时间复杂度Θ(n 2 ),因为最里面的循环执行O(1)工作,而中间循环将运行1 + 2 + 3 + 4 + ... + n =Θ(n 2 )次。请注意,它并不完全是100n 2 ,因为求和并不完全是n 2 ,但它已接近。
现在,让我们看一下递归部分:
for i=1 to 7
Alg(n-2);
对于初学者来说,这简直太傻了!没有理由你想做这样的事情。但是,也就是说,我们可以说这是对大小为n-2的输入的7次调用。
因此,我们得到这种递归关系:
T(n)= 7T(n - 2)+Θ(n 2 )[如果n≥3]
T(n)=Θ(1)[否则]
现在我们已经复发了,我们可以开始计算出时间的复杂性。这最终有点棘手。如果你考虑我们最终会做多少工作,我们就会得到那个
由此,我们立即获得Ω的下限(7 n / 2 ),因为这是将要进行的调用次数。每次调用都会对O(n 2 )起作用,因此我们可以获得O的上限(n 2 7 n / 2 )。真正的价值在于那里的某个地方,虽然老实说我不知道如何弄清楚它是什么。对不起!
希望这有帮助!
答案 1 :(得分:0)
正式方法是执行以下操作:
当涉及到递归调用的数量时,可以从源代码直观地推断出流行增长的顺序。
具有2个递归调用的算法具有2 ^ n的复杂度; 3个递归调用复杂性3 ^ n等等。