为什么学习算法
简单编程问题
- 可以进行线性扫描
- 无法做到更好
- 程序是否工作很显而易见
算法问题
- 不清楚如何做
- 简单方法往往效率很低
- 有优化空间
人工智能问题很难描述清楚
而本课主要研究的是算法问题
明确且清晰描述的算法问题
很难高效执行的算法问题
从问题描述到提出算法,直观算法往往很低效。因此才需要研究算法。
斐波那契数列
0, 1, 1, 2, 3, 5, 8, 13, 21 ,34,…
最早是为了研究兔子繁殖提出的模型
定义很简单:
给出输入n,求序列为n的斐波那契数列元素作为输出,直观算法如下:
我们可以简单将执行代码的行数作为运行时间的单位,这样我们有:
由此我们可以知道
T(n)>=Fn
也就是说程序的运行时间也和斐波那契数列一样高速增长,显然这远远超出了我们硬件所能支持的水平。
而直观算法速度慢的原因就是在计算前两项的过程中存在大量重复计算。
高效算法:
最大公约数
直观算法:
此处循环终止条件应为min(A, B)
关键引理如下:
证明:
欧几里得算法
每次循环大概把输入降为原来的一半,所以时间复杂度大概为log(ab)
计算时间复杂度
我们想要了解具有普遍意义的运行时间,也就是时间复杂度。
同时这个结果应当适用于较大量的输入
Asymptotic Notation
我们要考虑的是程序运行时间和输入数据规模的关系。
Bio-O Notation
使用big-O notation 来描述运行时间有几个优点:
- 可以清晰描述运行时间随输入数据规模变化的增长率
- 表示符号更加简洁
使用Big-O
常见规则:
举例:斐波那契数列
设计的几种境界