条件语句的时间复杂度

时间:2019-04-11 10:00:23

标签: algorithm

如何使用条件语句计算时间复杂度

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)?

1 个答案:

答案 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));
});

这仅是示例,不能作为证明。