如何计算时间复杂度和空间复杂度

看B站UP主 图灵星球TuringPlanet 的视频做的笔记,原视频: 时间复杂度和空间复杂度,大O表示法【数据结构和算法入门2】
做完笔记发现原作者有详细文字教程:文字教程 ,于是又参考人家的教程将自己的笔记完善和修改了一下。

时间复杂度

        一个算法的执行时间受很多因素的影响,(例如执行算法的机器的好坏),所以我们不能仅依靠算法的执行时间来判断算法的好坏。因此我们用“大O表示法”来描述算法的渐进时间复杂度:
T ( n ) = O ( f ( n ) ) T(n)=O(f(n)) T(n)=O(f(n))
其中 T ( n ) T(n) T(n)表示渐进时间复杂度, f ( n ) f(n) f(n)表示代码执行次数, O O O表示正比例关系。

两个例子

栗子1

for(let i=1;i<=n;i++)
	x++;

上面这段代码的执行次数为 ( 2 + 3 N ) (2+3N) (2+3N) 次:

  • i = 1 ; → i=1; → i=1; 执行 1 1 1次;
  • i < = n i<=n i<=n x + + x++ x++ n + + ; → n++; → n++; 执行 N N N次,共执行 3 N 3N 3N次;
  • 最后还要执行一次 i < = n i<=n i<=n.

所以时间复杂度为: O ( 2 + 3 N ) = O ( N ) O(2+3N)=O(N) O(2+3N)=O(N)

【问:为什么这样简化?】
【答:因为 O O O计算的是在 N N N趋于 + ∞ + \infty +时的情况,所以常数 2 2 2和倍数 3 3 3就没有意义了。】

计算复杂度时,取最高次项,并去掉该项的次数

栗子2

for(let i=1;i<=n;i++)
	x++;
for(let i=1;i<=n;i++)
	for(let j=1;j<=n;j++)
		x++;

时间复杂度: O ( N + N 2 ) = O ( N 2 ) O(N+N^2)=O(N^2) O(N+N2)=O(N2)。【当 N → + ∞ N → + \infty N+时, N N N远小于 N 2 N^2 N2

常用的时间复杂度:

常见复杂度时间量级

  • 常数阶 O ( 1 ) O(1) O(1)
  • 对数阶 O ( l o g N ) O(logN) O(logN)
  • 线性阶 O ( n ) O(n) O(n)
  • 线性对数阶 O ( n l o g N ) O(nlogN) O(nlogN)
  • 平方阶 O ( n 2 ) O(n^2) O(n2)
  • 立方阶 O ( n 3 ) O(n^3) O(n3)
  • K次方阶 O ( n k ) O(n^k) O(nk)
  • 指数阶 O ( 2 n ) O(2^n) O(2n)
  • 阶乘 O ( n ! ) O(n!) O(n!)

时间复杂度从上到下越来越大,即执行效率越来越低。

线性阶 O ( 1 ) O(1) O(1)

只要没有循环或递归等复杂逻辑,无论代码执行多少行,复杂度都为 O ( 1 ) O(1) O(1)

let x=0;
let y=1;
let temp=x;
x=y;
y=temp;

上述代码执行时,消耗的时间不会随着特定变量的增长而增长,即使有几万行这样的代码,我们都可以用 O ( 1 ) O(1) O(1)来表示它的时间复杂度。

常数阶 O ( n ) O(n) O(n)

栗子1。

对数阶 O ( l o g n ) O(logn) O(logn)
let i=1;
while(i<n)
	i*=2;

分析:计算跳出循环需要执行多少次。 2 k = n → k = l o g 2 n 2^k=n → k=log_2n 2k=nk=log2n,因此复杂度为 O ( l o g n ) O(logn) O(logn)

线性对数阶 O ( n l o g n ) O(nlogn) O(nlogn)
for(let i=0;i<=n;i++){
    let x=1;
    while(x<n){
        x*=2;
    }
}

分析:while外面加了一层 n n n 次循环,所以复杂度为: O ( n l o g n ) O(nlogn) O(nlogn)

平方阶 O ( n 2 ) O(n^2) O(n2)
for(let i=0;i<=n;i++){
    for(let j=0;j<=n;j++)
        x++;
}

分析:很容易得知复杂度为 O ( n 2 ) O(n^2) O(n2)

  • 如果把第二层循环中的 n n n 换为 m m m, 则复杂度为: O ( n m ) O(nm) O(nm)
  • 同理,如果是三层循环,那么复杂度为: O ( n 3 ) O(n^3) O(n3)。如果是 k k k 层循环,复杂度为: O ( n k ) O(n^k) O(nk)

空间复杂度

空间复杂度:算法所需的内存空间增长的趋势。

常用的空间复杂度:

  • O ( 1 ) O(1) O(1) O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度用 S ( N ) S(N) S(N)代表。
O ( 1 ) O(1) O(1)空间复杂度

如果算法执行所需要的临时空间不随着某个变量n的大小而变化,则算法空间复杂度为一个常量,可表示为 O(1):

let x = 0;
let y = 0;
x++;
y++;
O ( n ) O(n) O(n)空间复杂度

这段代创建了一个长度为 n n n 的数组,在循环中为其中的元素赋值。因此,这段代码的「空间复杂度」取决于 array 的长度,也就是 n n n,所以 S ( n ) = O ( n ) S(n) = O(n) S(n)=O(n)

var array = new Array(n);  // n是数组长度
for(let i=0;i<n;i++)
    array[i]=i;
O ( n 2 ) O(n^2) O(n2)空间复杂度

给一个 n × n n \times n n×n 的矩阵赋值时,空间复杂度为 O ( n 2 ) O(n^2) O(n2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值