完整的问题是
假设我们有一个功能
void foo(int n){
int i = n;
while(i > 0){
//do an O(n) operation
//do some O(1) operations
i = sqrt(i) - 1;
}
}
我只需要找到渐近边界,但我不能这样做,直到我弄清楚循环实际运行了多少次。我猜测的是另一个涉及平方根的求和,但我不确定如何开始。
答案 0 :(得分:4)
您想要找到循环执行的次数。
如果我< 2,然后循环最多执行两次。
因此如果我< 4循环最多执行3次。
因此如果我< 16循环最多执行4次。
因此如果我< 256循环最多执行5次。
...
等
你看,如果我< 2 ^(2 ^ m),然后循环最多执行(m + 2)次。
这意味着它将执行的次数的顺序是log(log(n)),
因为我从n开始。
因此整体复杂性为O(n*log(log(n))
。
(即每次迭代中O(1)次操作的数量是否恒定。)
答案 1 :(得分:2)
与Petar相同的O(n log log n),但这里有一些更清晰的界限。如果i = floor(sqrt(i))-1,
如果n< 1,它循环零时间
如果n< 2²,最多循环1次
如果n< (2²+ 1)²=5²,最多循环2次
如果n< (5²+ 1)²=26²,最多循环3次
如果n< (26²+ 1)²=677²,最多循环4次
根据On-Line Encyclopedia of Integer Sequences,这个序列(1,2,5,26,677,...)渐近到1.22 ^(2 ^ k)[并且第k个数字代表数字高度最多的二叉树k]。所以对于数字n,循环数是O(log log n),你的算法是O(n log log n)。