给出此算法(a> 0,b> 0):
while(a>=b){
k=1;
while(a>=k*b){
a = a - k*b;
k++;
}
}
我的问题:我必须找到该算法的时间复杂度,要做到这一点,我必须找到指令数量,但找不到。有没有办法找到这个数字,如果没有,我如何找到它的时间复杂度?
我所做的事情:首先,我尝试查找第一个循环的迭代次数,并找到了一个模式:a_i = a-(i(i + 1)/ 2) * b其中,i是迭代次数。我已经花了几个小时对其进行了一些操作,但是找不到任何相关的东西(我发现了奇怪的结果,例如q²<= a / b
答案 0 :(得分:3)
您已经正确计算出内部循环的第a
次迭代后的i
的值是:
a_j0
是第a
外循环开始时j
的值。内循环的停止条件是:
可以解决二次不等式
因此,内部循环大约为O(sqrt(a_j0 / b))
。 a
的 next 起始值满足:
大致缩放为sqrt(2b * a_j0)
。准确地计算时间复杂度将非常繁琐,因此让我们从此处开始应用上述近似值:
用a_n
代替a_j0
,其中t_n
是内部循环的运行时间–当然,总的时间复杂度只是t_n
的总和。请注意,第一项由n = 1
给出,并且a
的输入值定义为a_0
。
在直接解决此重复项之前,请注意,由于第二项t_2
已经与第一项t_1
的平方根成比例,因此后者在总和中占所有其他项的作用。
因此,总时间复杂度仅为
O(sqrt(a / b))
。
更新:数值测试。
请注意,由于a
值的所有变化都与b
成比例,并且所有循环条件也与b
成比例,因此可以对该函数进行“归一化“ ,只需设置b = 1
并仅更改a
。
JavaScript测试功能,它测量内部循环执行的次数:
function T(n)
{
let t = 0, k = 0;
while (n >= 1) {
k = 1;
while (n >= k) {
n -= k;
k++; t++;
}
}
return t;
}
sqrt(n)
对T(n)
的图:
令人信服的直线,确认时间复杂度的确是一半。