文章目录

  • 一、算法的时间复杂度
  • 1.1 度量算法执行时间的两种方法
  • 1.1.1 事后统计
  • 1.1.2 事前估算
  • 1.2 时间频度
  • 1.2.1 基本介绍
  • 1.2.2 举例说明:基本案例
  • 1.2.3 举例说明:忽略常数项
  • 1.2.4 举例说明:忽略低次项
  • 1.2.5 举例说明:忽略系数
  • 1.3 时间复杂度
  • 1.4 常见的时间复杂度
  • 1.4.1 常数阶 O(1)
  • 1.4.2 对数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记
  • 1.4.3 线性阶 O(n)
  • 1.4.4 线性对数阶尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_02
  • 1.4.5 平方阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_03
  • 1.4.6 立方阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_04
  • 1.4.7 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_05
  • 1.5 平均时间复杂度和最坏时间复杂度
  • 二、算法的空间复杂度
  • 2.1 基本介绍



一、算法的时间复杂度

1.1 度量算法执行时间的两种方法

1.1.1 事后统计

直接运行一遍程序,记录程序运行的用时

这种方法可行, 但是有两个问题:

  • 一是要想对设计的算法的运行性能进行评测, 需要实际运行该程序;
  • 二是所得时间的统计量依赖于计算机的硬件、软件等环境因素, 这种方式, 要在同一台计算机的相同状态下运行, 才能比较哪个算法速度更快。

1.1.2 事前估算

通过分析某个算法的时间复杂度来判断哪个算法更优

1.2 时间频度

1.2.1 基本介绍

时间频度: 一个算法花费的时间与算法中语句的执行次数成正比例, 哪个算法中语句执行次数多, 它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_06

1.2.2 举例说明:基本案例

比如计算1-100所有数字之和,我们设计两种算法

第一种算法:T(n) = n + 1

int total = 0;
        int end = 100;
        for (int i = 1; i <= end; i++) {
            total += i;
        }

第二种算法:T(n) = 1

int end = 100;
        // 等差数列求和公式
        int total = (1 + end) * end / 2;

1.2.3 举例说明:忽略常数项

尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_07

结论

  • 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_08尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_09 随着 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10
  • 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_11尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_12 随着 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10

1.2.4 举例说明:忽略低次项

尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_14

结论

  • 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_15尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_16 随着 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_17 变大, 执行曲线无限接近, 可以忽略 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_18
  • 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_19尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_20 随着 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10 变大,执行曲线无限接近, 可以忽略 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_22

1.2.5 举例说明:忽略系数

尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_23

结论

  • 随着 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10 值变大, 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_25尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_26, 执行曲线重合, 说明这种情况下, 5 和 3 可以忽略。
  • 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_27尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_28, 执行曲线分离, 说明多少次方是关键

1.3 时间复杂度

1. 一般情况下, 算法中的基本操作语句的重复执行次数是问题规模 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_29 的某个函数, 用 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_30, 若有某个辅 助函数 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_31, 使得当 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10 趋近于无穷大时, 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_33 的极限值为不等于零的常数, 则称 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_31尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_35 的同数量级函数。 记作 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_36, 称 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_37

2. 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_38。如: 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_39尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_40 它们的 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_41 不同, 但时间复杂度相同, 都为 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_42

3. 计算时间复杂度的方法:

  • 用常数 1 代替运行时间中的所有加法常数 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_43
  • 修改后的运行次数函数中, 只保留最高阶项 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_44
  • 去除最高阶项的系数 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_45

1.4 常见的时间复杂度

  • 常数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_46
  • 对数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_47
  • 线性阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_48
  • 线性对数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_49
  • 平方阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_50
  • 立方阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_51
  • 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_52 矢阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_53
  • 指数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_54

常见的时间复杂度对应的图

尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_55

说明

  • 常见的算法时间复杂度由小到大依次为: 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_56 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_57, 随着问题规模 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10
  • 从图中可见, 我们应该尽可能避免使用指数阶的算法

1.4.1 常数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_59

无论代码执行了多少行,只要没有循环等复杂结构,那这个代码的时间复杂度就是 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_46

int i = 1;
        int j = 2;
        int k = j - i;
        ++k;
        j++;
        i += 1;

上述代码在执行的时侯, 它消耗的时候并不随着某个变量的增长而增长, 那么无论这类代码有多长, 即使有几万、几十万行, 都可以用 O(1) 来表示它的时间复杂度。

1.4.2 对数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_61

在while循环里面, 每次都将 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_62 乘以 2 , 乘完之后, 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_62 距离 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10 就越来越近了。
假设循环 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_65 次之后, 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_66 就大于 2 了, 此时这个循环就退出了, 也就是说 2 的 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_65 次方等于 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_17, 那么 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_69 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_70 也就是说当循环 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_70 次以后, 这个代码就结束了。
因此这个代码的时间复杂度为: 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_72
尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_72 的这个 2 时间上是根据代码变化的, 假设是 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_74, 则是 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_75.

int i = 1;
        while (i < n) {
            i = i * 2;
        }

1.4.3 线性阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_76

说明: 这段代码, for循环里面的代码会执行 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_17 遍, 因此它消耗的时间是随着 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_17 的变化而变 化的, 因此这类代码都可以用 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_79

for (int i = 0; i < n; i++) {
            // some O(1) code ...
        }

1.4.4 线性对数阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_80

线性对数阶就很好理解了,就是将时间复杂度为 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_81的代码循环执行 n 次

for (int i = 0; i < n; i++) {
        
        int k = 1;
        while (k < n) {
            k = k * 2;
        }
        
    }

1.4.5 平方阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_82

2层for循环,最内层是O(1)的代码

for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                // some O(1) code ...
            }
        }

1.4.6 立方阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_83

3层for循环,最内层是O(1)的代码

for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    // some O(1) code ...
                }
            }
        }

1.4.7 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_java_84 次方阶 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_尚硅谷MySQL数据库高级 笔记_85

尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法复杂度_86

for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    for (int l = 0; l < n; l++) {
                        for (int m = 0; m < n; m++) {
                            ......
                        }
                    }
                }
            }
        }

1.5 平均时间复杂度和最坏时间复杂度

  • 平均时间复杂度是指所有可能的输入实例均以等概率出现的情况下, 该算法的运行时间。
  • 最坏情况下的时间复杂度称最坏时间复杂度。一般讨论的时间复杂度均是最坏情况下的时间复杂度。这样做的 原因是: 最坏情况下的时间复杂度是算法在任何输入实例上运行时间的界限, 这就保证了算法的运行时间不会 比最坏情况更长。
  • 平均时间复杂度和最坏时间复杂度是否一致, 和算法有关(如下图所示)。

尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_时间复杂度_87


二、算法的空间复杂度

2.1 基本介绍

  • 类似于时间复杂度的讨论, 一个算法的空间复杂度(Space Complexity)定义为该算法所耗费的存储空间, 它也是 问题规模 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10
  • 空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。有的算法需要占用的 临时工作单元数与解决问题的规模 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10 有关, 它随着 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10 的增大而增大, 当 尚硅谷MySQL数据库高级 笔记 尚硅谷数据结构与算法_算法_10
  • 在做算法分析时, 主要讨论的是时间复杂度。从用户使用体验上看, 更看重的程序执行的速度。一些缓存产品 (redis, memcache)和算法(基数排序)本质就是用空间换时间.