python数据结构与算法分析_算法与数据结构-算法分析

大 O 表示法

我们从一个计算矩阵的例子来引入,这里我参考了 《Data Structures and Algorithms in Python》中给的一个例子:

考虑计算一个 n * n 矩阵所有元素的和(如果你不知道矩阵,就理解为一个二维数组):

⎡⎣⎢036147258⎤⎦⎥[012345678]

这里列举两种方式:

3b451c8ff552cd9d5af1041eb0410628.png

6378d944fc7d75e51b4b2f26425fbb26.png

v1 版本的关键操作在 j 循环里,两步加法操作,由于嵌套在第一个循环里,操作步骤是 (2n)∗n=2n2(2n)∗n=2n2。

v2 版本的 total_sum 只有 n 次操作,它的操作次数是 n+n∗n=n2+nn+n∗n=n2+n。

这里你可能还感觉不到它们有多大差别,因为计算机执行的太快了,但是当 n 增长特别快的时候,总的操作次数差距就很明显了:

cf7c10c30034002cf0a4abd925a4dae4.png

6378d944fc7d75e51b4b2f26425fbb26.png

通常我们不太关注每个算法具体执行了多少次,而更关心随着输入规模 n 的增加,算法运行时间将以什么速度增加。为此计算机科学家定义了一个符号, 用来表示在最糟糕的情况下算法的运行时间,大 O 符号,在数学上称之为渐进上界(《算法导论》)。

如何计算时间复杂度

上边我们列举了两个版本的计算矩阵和的代码,你看到了两个公式:

  • v1: 2n∗n=2n22n∗n=2n2
  • v2: n+n∗n=n+n2n+n∗n=n+n2

当 n 非常大的时候,n2n2 的数值这里将占主导,我们可以忽略 n 的影响

  • v1: 2n∗n=2n22n∗n=2n2
  • v2: n+n∗n=n+n2≤2n2n+n∗n=n+n2≤2n2

这里我们可以认为两个算法的时间复杂度均为 O(n2)O(n2)

常用时间复杂度

这里我们列举一些常用的时间复杂度,按照增长速度排序,日常我们的业务代码中最常用的是指数之前的复杂度,指数和阶乘的增长速度非常快, 当输入比较大的时候用在业务代码里是不可接受的。

154a2e86b0f6c59f801212beb2e58b47.png

6378d944fc7d75e51b4b2f26425fbb26.png

空间复杂度

相比时间复杂度,空间复杂度讨论比较少。因为用户老爷等不及,况且现在存储越来越白菜价了,更多时候我们为了提升响应速度宁可多 使用点空间。 空间复杂度相对好算一些,就是每个元素的空间占用乘以总的元素数,有些算法需要额外的空间存储,有些可以本地解决。 如果能本地搞定的我们成为 in place 的,原地操作,比如交换一个 数组中的某两个位置的元素。但是有些操作可能就需要申请额外的空间 来完成算法了,后边我们介绍排序算法的时候会讲到。

常见复杂度增长趋势图

为了让你有个直观的感觉,我们来看看一些经典的时间复杂度和对应的增长趋势图,不同函数在输入规模增长的时候很快就会有巨大的增长差异

d5a4a547e831f9f96d14e5d222234d38.png

6378d944fc7d75e51b4b2f26425fbb26.png

16a14d76393e1473ca0ec0097a750cf3.png

6378d944fc7d75e51b4b2f26425fbb26.png

时间换空间,空间换时间

有一些时候时间和空间两者不可兼得,我们会牺牲其中之一来换取另一个。

空间换时间:比如典型的就是 python 中的集合(后面会讲到它的实现原理),虽然它比较浪费空间,但是却能用 O(1) 的时间复杂度来判重。

时间换空间:当我们空间不够用,典型的就是缓存失效算法,我们不可能缓存下无限容量的数据,就会使用一些缓存淘汰算法来保证空间可用。

思考题

  • 回头看看前几章我们讲到的数据结构,以及每个操作的时间复杂度,你能理解了吗?
  • 二分查找是针对有序元素的一种经典的查找算法,你知道的它的时间复杂度吗?你能简单证明下吗。
  • 斐波那契数列你肯定很熟悉,它的公式是 F(n) = F(n-1) + F(n-2),你知道计算一个斐波那契数 F(n) 的时间复杂度吗?你会用数学公式证明吗?
  • 你能指出时间和空间权衡的例子吗?往往很多高效的数据结构能同时兼顾时间和空间复杂度,但是有时候我们却得做出一定的权衡
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值