时间复杂度分析(含习题)

503 阅读3分钟

复杂度

复杂度包括时间复杂度与空间复杂度,算法中数据的存储往往并不是问题,因此算法更注重用空间换时间。本文介绍的是时间复杂度。

1.O(1)

let n; //执行一次,时间复杂度为O(1)
n+=1;//执行一次O(1)

执行次数是一个常数项时,时间复杂度就用O(1)来表示。

2.O(n)

for(let i=0;i<n;i++){ // 执行n次
    console.log('...')
}

for循环的次数是随着n的变化而变化,所以为n

我们把算法的执行次数用T(n)表示,函数执行的时间复杂度用F(n)表示。接下来引入时间复杂度:

当n>=2时,f(n)= n^2总是大于或等于 T(n+2),即F(n)=T(n),也就是说F(n)是T(n)的上界。此时我们可以用F(n)的增长速度度量T(n)的增长速度,所以说这个算法的时间复杂度是O(f(n))

3. O(logn)

let i = 1
while (i < 64) {
    console.log(i);
    i *= 2
}

这就是数学中所学的log函数,数学表示的话就是x=log(a)(N),即a^x=N,x就叫做以a为底N的对数。上例中用x就记做x=log(2)(N),那么这个对数x其实就是函数执行的次数,即T(n)=xx用时间复杂度就表示为O(logn),F(n)=O(logn),即T(n)=F(n)。

4.O(n^2)

大O表示法默认该算法所有可能最上界的最下界。

for(let i=0;i<n;i++){ // 执行n次
    for(let i=0;i<n;i++){ // 执行n次
        for(let i=0;i<n;i++){ // 执行n次
            console.log('...')
        }
    }
}

T(n)=n^2,用时间复杂度就表示为F(n)=(O(n^2)),即T(n)=F(n)。那么T(n)=n^3、依次都是成立的,因为第一个F(n)用来度量T(n)是最接近的,也是最好的选择,所以为O(n^2)。

习题

如何根据函数T(n)根据函数执行次数得出事件复杂度F(n)?

常数项对函数执行时间的增长速度是没有影响的,例如T(n)=c,当c是一个常数项时:

var a = 1 // 执行一次
console.log(a) //执行一次

此时T(n)=2,函数时间复杂度表示为F(n) = O(1)

1.一个循环体的时间复杂度用O(n)来表示,循环次数用m来表示,则下面这个例子就是O(n*m)

for(let i=0;i<n;i++){ //循环次数n次
    console.log(i) //时间复杂度O(1)
}

2.对于多个循环体

for(let i=0;i<n;i++){ // 执行n次
    for(let i=0;i<n;i++){ // 执行n次
        console.log('...') //时间复杂度为O(1)
    }
}

函数时间复杂度表示为F(O* n * n * 1),即O(n^2)。

3.对于执行顺序相同的for循环或者if/else中的for循环,总时间复杂度=时间复杂度最大的那个.

    // 第一部分时间复杂度为 O(n^2)
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            console.log("1");
        }
    }
    // 第二部分时间复杂度为 O(n)
    for(int j = 0; j < n; j++) {
        console.log("2");
    }

即都是O(n^2)。

4.求该函数的时间复杂度

let i = 1
while (i < 64) {
    console.log(i);
    i *= 2
}

和上述的3. O(logn)介绍相同。