文章目录
算法分析基础
1. 效率的定义
- 当实现一个算法时,如果在真实的案例上,他能运行的更快,那么就是有效的
- 如果一个算法与蛮力搜索相比,在最坏情况下达到质量上更好的性能,则是有效的
- 如果一个算法有多项式运行时间,他就是有效的
之所以对效率给出这样详细的定义,是为了表达:对于某些问题不存在有效的算法
2. O、 Θ \Theta Θ 和 Ω \Omega Ω
上界:如果对于函数T(n),有充分大的n,函数T(n)小于f(n)的某个常数倍,则T(n)=O(f(n)),此时我们说f是T的渐进上界
下界:如果对于函数T(n),有充分大的n,函数T(n)大于f(n)的某个常数倍,则T(n)= Ω \Omega Ω(f(n)),此时我们说f是T的渐进下界
渐进的紧的界:如果lim f(n)/g(n)=c>0 那么f(n)= Θ \Theta Θ(g(n)),此时也可以说g(n)即是f(n)的上界,也是其下界
3. 性质
-
传递性:这三个符号都具有传递性,例如:
> If f=O(g) and g=O(h) then f=O(h)
-
函数的和:如果函数的上界对k个函数都适用,则对这k个函数的和也适用
if f=O(h) and g=O(h) then f+g=O(h)
-
如果 g=O(f) then f+g= Θ \Theta Θ (f)
proof: 首先很容易由 f+g≥f 得到 f+g= Ω \Omega Ω(f)
已知g=O(f) 且易知f=O(f),根据第二条性质 f+g=O(f)
由此,f+g= Θ \Theta Θ (f)
4. 某些常见函数的渐进界
-
多项式函数
通常直接取最高次项即可: 2n2+13n+8=O(n2)
-
对数函数
对于对数函数通常不写底数,原因是通过换底公式很容易可以得到
logan=1/logba · logbn
我们可以很容易更换函数的底,而前面的常数项无关紧要,所以我们通常省略函数的底
5. 例题
5.1 一些比较复杂的函数排列
- 可以使用取对数的方式进行比较
- 注意归类,归为多项式,对数和指数函数不同类别分别进行比较
5.2 判断题
已知 f(n)=O(g(n))
判断对错
- log2f(n)=O(log2g(n))
- 2f(n)=O(2g(n))
- f(n)2=O(g(n)2)
做这种题目的时候,应该写出算法带入计算,不能想当然的理解
解题思路:已知 f(n)≤c·g(n)
那么有 f(n)2=c2g(n)2 故第三条正确
而另外两条都不能满足这样的式子,对于第一条,当f=2,g=1时不满足条件,对于第二条当f=4n,g=2n时不满足条件
5.3 瓶子摔碎高度问题
假设你需要知道在第几节阶梯上可以摔碎一个瓶子,如果你采用从第一级开始往上一节节的实验的方式,你的复杂度是O(n)且只需要一个瓶子,如果使用二分法进行查找,则复杂度是O(logn)但是存在的问题是会消耗更多的瓶子。
那么假设只给你2个瓶子,你有没有办法用小于O(n)的时间找到瓶子摔碎的临界高度呢?
解决方案:把台阶分成n1/2个区间,则每个区间的长度为n1/2,让第一个瓶子分别在n1/2,2n1/2,3n1/2……的高度下进行实验直至瓶子 摔碎为止,假设瓶子在m*n1/2的高度摔碎,则用第二个瓶子在(m-1)n1/2到mn1/2的高度区间里一级一级的进行实验,这次实验也最多 只需要进行n1/2次。将两次实验所需要的时间加和在一起,总共所需要的时间为2n1/2。满足题目要求
那么如果给你k>2个瓶子,你能否设计出一个算法,使得瓶子越多,则时间复杂度越低呢?
解决方案:其实方法和上一题类似,第一次将阶梯分为n1/k个区间,则每个区间的长度为nk-1/k,让第一个瓶子在这n1/k个区间里进行实 验,当确定为某个区间之后,再把这个确定的区间分成n1/k个区间,让第二个瓶子在这些区间里进行实验……直到最后选定的高度就为 n1/k的区间为止,对于这k个瓶子,每个瓶子的最坏复杂度都是n1/k,则复杂度就为kn1/k。满足条件。