Algorithm 这个嵌套for循环重复加倍其计数器的代码的复杂性是什么?
在《编程访谈》一书中,它说下面程序的复杂性是O(N),但我不明白这是怎么可能的。有人能解释为什么会这样吗Algorithm 这个嵌套for循环重复加倍其计数器的代码的复杂性是什么?,algorithm,time-complexity,big-o,complexity-theory,Algorithm,Time Complexity,Big O,Complexity Theory,在《编程访谈》一书中,它说下面程序的复杂性是O(N),但我不明白这是怎么可能的。有人能解释为什么会这样吗 int var = 2; for (int i = 0; i < N; i++) { for (int j = i+1; j < N; j *= 2) { var += var; } } int-var=2; 对于(int i=0;i(n/2)-->1次迭代 (n/2)-1>=i>(n/4)-->2次迭代 (n/4)>=i>(n/8)-->3次迭代 (n
int var = 2;
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j *= 2) {
var += var;
}
}
int-var=2;
对于(int i=0;i
你需要一点数学知识才能明白这一点。内部循环迭代Θ(1+log[N/(i+1)])
次(由于i>=N/2
,[N/(i+1)]=1
且对数为0,循环迭代一次,因此1+
是必需的)j
取值(i+1)*2^k
,直到它至少与N
一样大,并且
(i+1)*2^k >= N <=> 2^k >= N/(i+1) <=> k >= log_2 (N/(i+1))
现在,他告诉我们
因此,我们发现所做的总功确实是
O(N)
@Daniel Fischer的答案是正确的
我想补充一点,该算法的准确运行时间如下:
这意味着:
外循环运行
n次。现在一切都取决于内部循环。
内部循环现在是一个棘手的问题
让我们如下:
i=0 --> j=1 ---> log(n) iterations
...
...
i=(n/2)-1 --> j=n/2 ---> 1 iteration.
i=(n/2) --> j=(n/2)+1 --->1 iteration.
i>(n/2)-->1次迭代
(n/2)-1>=i>(n/4)-->2次迭代
(n/4)>=i>(n/8)-->3次迭代
(n/8)>=i>(n/16)-->4次迭代
(n/16)>=i>(n/32)-->5次迭代
(n/2)*1+(n/4)*2+(n/8)*3+(n/16)*4+…+[n/(2^i)]*i
N-1
n*∑ [i/(2^i)]=<2*n
i=0
-->O(n)
“它说”什么?告诉我们你在这里假设的是什么。我做了编辑,很抱歉含糊不清。这个循环结构与heapify算法的循环结构密切相关,分析将非常相似。ASCII方程的功劳/Art你是指第二个框中的j
而不是I
,不。我的意思是I
,当外循环在这些范围内时,j将被分配1 2 3 4 5…
不同的值(迭代次数)顺便说一句,很好的声誉增益:)。几天前你有800个,但是j
是指数增长的变量,而不是像i
那样线性增长的变量?我不认为迭代次数会像你说的那样线性增加。@meowgoesthedog当然j是指数增长的。当i
为n/2时,j将为n/2+1,然后循环将中断。因此,在内部循环停止之前,j只有1个值(运行了一次迭代)。不,当i=n/2
时,内部循环不会中断(事实上,直到i=n-1
),因为j*=2
发生在第一次内部循环迭代之后,并且只有到那时内部循环才会中断。谢谢:)我很幸运
log N! = N*log N - N + O(log N)
i=0 --> j=1 ---> log(n) iterations
...
...
i=(n/2)-1 --> j=n/2 ---> 1 iteration.
i=(n/2) --> j=(n/2)+1 --->1 iteration.
i > (n/2) ---> 1 iteration
(n/2)-1 >= i > (n/4) ---> 2 iterations
(n/4) >= i > (n/8) ---> 3 iterations
(n/8) >= i > (n/16) ---> 4 iterations
(n/16) >= i > (n/32) ---> 5 iterations
(n/2)*1 + (n/4)*2 + (n/8)*3 + (n/16)*4 + ... + [n/(2^i)]*i
N-1
n*∑ [i/(2^i)] =< 2*n
i=0
--> O(n)