18天算法基础系列课(一)复杂度

171 阅读1分钟

什么是算法:算法是解决一系列特定问题的执行步骤

如何判定算法好坏:

事后统计法

如果单从执行效率上评估,我们会想到比较对同一组数据处理时间,这种方法叫做事后统计法,这种方案有比较明显的缺点:

  • 执行时间依赖于硬件以及运行时等不确定因素影响
  • 必须编写对应的测试代码
  • 测试数据难保证公正性
大O表示法

一般从以下维度评估算法优劣

  • 确定性、可读性、健壮性(对不合理输入的反应和处理能力)
  • 时间复杂度(time comflexity):估算程序指令执行次数(执行时间)
  • 空间复杂度(space comflexity):估算所需占用的存储空间

为了描述算法复杂度,使用“O”表示,O表示数据规模n对应的复杂度

使用数字即可表示复杂度,就记为O(1)

  • 9->O(1)
    使用n表示复杂度,记为O(n)
  • 2n+3 -> O(n)
    使用n2n^2表示复杂度,记为O(n2n^2)
  • n2+2n+1n^2+2n+1->O(n2n^2) 以次类推,可以写成O(n3n^3),O(n4n^4)等等
常见的复杂度
执行次数复杂度非正式术语
9O(1)常数阶
2n+3O(n)线性阶
log2nlog_{2}{n}O(logn)对数阶
n2+2n+1n^2+2n+1O(n2n^2)平方阶
2n+nlog2n+102n+nlog_{2}{n}+10O(nlogn)nlogn阶
n3+4n+1n^3+4n+1O(n3n^3)立方阶
2n2^nO(2n2^n)指数阶

常用复杂度排序: O(1) < O(logn) < O(n) < O(nlogn) < O(n2n^2) < O(n3n^3) < O(2n2^n) < O(n!) < O(nnn^n)

注意:大O表示法仅仅是一个粗略的分析模型,是一种估算,在短时间内分析出算法执行效率

后续还会穿插介绍算法评价的其他角度:

  • 最好最坏复杂度
  • 均摊复杂度
  • 复杂度震荡
  • 平均复杂度

借助函数生成工具计算算法复杂度:zh.numberempire.com/graphingcal…

算法复杂度案例

O(1)

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

O(n)

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

O(n2n^2)

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

O(logn)

// 执行次数 = log2(n)
// O(logn)
while ((n = n / 2) > 0) {
   System.out.println(n);
}

O(nlogn)

执行次数 = log2(n)*n
for (int i = 1; i < n; i = i * 2) {
   for (int j = 0; j < n; j++) {
      System.out.println("test");
   }
}