如何使用条件语句计算时间复杂度
i=1
while i<=n
j=1
while i<=n
if i==j
k=1
while k<=j
k+=1
print("hello")
else
print(""world)
j*=2
i*=2
时间复杂度是θ(nlgn)还是θ(lgn * lgn)?
答案 0 :(得分:4)
假设第二个while
循环应读取while j<=n
,则时间复杂度为:
O(n)
而决定因素正是 k 上的循环。
我们有:
i=1
while i<=n
j=1
while j<=n
if i==j
k=1
while k<=j
k+=1
print("hello")
else
print("world")
j*=2
i*=2
i==j
的情况在外循环的每次迭代中都会发生一次( i 发生变化),并且可以独立于 j 的值,并从 j 的循环中取出:
i=1
while i<=n
j=1
while j<=n
if i!=j
print("world")
j*=2
k=1
while k<=i
k+=1
print("hello")
i*=2
这会更改print
输出的顺序,但这与确定时间复杂度无关。我们甚至可以进一步拆分:
i=1
while i<=n
j=1
while j<=n
if i!=j
print("world")
j*=2
i*=2
i=1
while i<=n
k=1
while k<=i
print("hello")
k+=1
i*=2
因此,对于第一个外部循环的一次迭代,其内部while循环迭代 logn 次。该内部循环的每次迭代都花费恒定的时间。在一种情况下(当 i 等于 j 时),工作量减少了一个常数,因此我们的时间复杂度为 O(logn)-O (1) = O(logn),用于此while
循环。
这使第一个外部循环的时间复杂度为:
O(登录)* O(登录)= O((登录)²)
对于第二个外部循环的一次迭代,其内部while循环迭代 i 次,因此我们得到的总迭代次数(当n为2的幂时)为 1 + 2 + 4 + 8 + ... + n ,即binary expansion-等于 2(2 logn )-1 = 2n-1 ,时间复杂度为:
O(2n-1)= O(n)
对于整体时间复杂度,我们取总和,即
O((logn)²)+ O(n)= O(n)。
为说明这种时间复杂性,请看一下此实现,其中每次执行时都会增加 n ,并对工作单位进行计数并返回。 n 与工作量之间的比率接近一个常数:
function work(n) {
var units = 0;
var i=1
while (i<=n) {
var j=1
while (j<=n) {
if (i==j) {
var k=1
while (k<=j) {
k+=1
//print("hello")
units++;
}
} else {
//print("world")
units++;
}
j*=2
}
i*=2
}
return units;
}
// Demo
setTimeout(function loop(n=1) {
var units = work(n);
console.log(`n=${n}, work=${units}, ratio=${units/n}`);
if (n < 100000000) setTimeout(loop.bind(null, n*2));
});
这仅是示例,不能作为证明。