算法的时间复杂度和空间复杂度分析

本文用大 O 表示法来表示时间复杂度和空间复杂度,大 O 并不代表代码真正执行时的复杂度,而是代表着一种变化趋势,所以在分析时,我们就可以忽略公式中的低阶、常量、系数。(通俗点说,我们只考虑执行次数最多的代码:同一层的代码,取其中量级更大的,嵌套的代码, 其复杂度为嵌套内外代码复杂度的乘积)

时间复杂度

常用时间复杂度

  1. O(1) 常量阶
  2. O(logn) 对数阶
  3. O(n) 线性阶
  4. O(nlogn) 线性对数阶
  5. O(n2) 平方阶 O(n3) 立方阶 … O(nk) k次方阶
  6. O(2n) 指数阶
  7. O(n!) 阶乘阶

O(1) 常量阶

O(1) 并不代表只执行一行代码,而是代表着代码执行次数不会随着 n 的变大而变大,是一个常量次数的执行。

int i = 1;
int j = 2;
System.out.println(i * j);

O(logn) 对数阶 & O(nlogn) 线性对数阶

对数时间复杂度是最难分析的一种时间复杂度,因为其并不像其他时间复杂度那样直观。

for(int i = 1; i <= n; i *= 2) {
  System.out.println(i);
}

上面的代码时间复杂度是 O(log2n),在采用大 O 计数法的时候,可以忽略系数,所以上面的时间复杂度我们认为是 O(logn)。

了解了 O(logn),O(nlogn) 就比较容易理解了。如果将上面的代码循环执行 n 次,就是 O(nlogn) 了。

for (int i = 0; i < n; i++) {
  for(int j = 1; j <= n; j *= 2) {
    System.out.println("i: " + i + ", j: " + j);
  }
}

O(n) 线性阶

for (int i = 0; i < n; i++) {
  System.out.println(i);
}

O(n2) 平方阶 & O(n3) 立方阶

for (int i = 0; i < n; i++) {
  for(int j = 0; j < n; j++) {
    System.out.println("i: " + i + ", j: " + j);
  }
}
for (int i = 0; i < n; i++) {
  for(int j = 0; j < n; j++) {
    for(int k = 0; k < n; k++) {
      System.out.println("i: " + i + ", j: " + j + ", k: " + k);
    }
  }
}

O(2n) 指数阶

for(int i = 0; i < Math.pow(2, n); i++) {
  System.out.println(i);
}

O(n!) 阶乘阶

public void f(int n) {
  if(n == 0) {
    return;
  }
  for(int i = 0; i < n; i++) {
    f(n - 1);
  }
}

空间复杂度

时间复杂度代表着算法的执行时间和数据规模大小的关系,而空间复杂度代表着算法的存储空间和数据规模大小的关系。

常用空间复杂度

  1. O(1) 常量阶
  2. O(n) 线性阶
  3. O(n2) 平方阶

空间复杂度的分析比时间复杂度要简单,我们需要分析的是,在代码执行过程中,需要额外申请的内存空间的大小和 n 之间的关系。

总结

分析时间复杂度和空间复杂度是学习算法必不可少的一步,需要勤加练习,最后附上一张图(代码撸多了就会发现,几乎所有的数据结构和算法都跑不出这几个)

在这里插入图片描述

参考:《数据结构与算法之美》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值