麻省理工大学公开课笔记:算法导论(三)——渐近符号、递归及解法

渐进符号

O 符号

形式化定义

f(n)=O(g(n)) 表示存在常数 c>0 , n0>0 ,使得对于所有的的 n>n0 ,有

0f(n)cg(n)

例子:

2n2=O(n3)

直观理解
和“小于或等于”类似。去掉首项系数(此处为2)和低阶项(此处无低阶项)之后,剩下的部分小于或等于 n3

注意
O 并不是对称的。不能说 n3O(n2) ,甚至也不能说 O(n3)=n2

集合定义

O(g(n))={f(n):c>0,n0>0,使n>n0,0f(n)cg(n)}

因此,不能简单理解 2n2 O(n3) 是“相等”的,而应该理解为 2n2 属于函数集 O(n3) ( 2(n2)O(n3) )

出现在公式中的集合符号(如 O )表示集合中的某一个函数,而不是集合整体。

例1: f(n)=n3+O(n2)
直观理解:表示了一个误差界限,即 f(n) 主要是由 n3 构成的,但也有一些 O(n2) 的低阶项
实际含义:存在一个函数 h(n)O(n2) ,使得 f(n)=n3+h(n)

例2: n2+O(n)=O(n2)
直观理解:“=”应该理解成“是”,而不是“等于”。等号左边隐含任意量词,等号右边隐含存在量词,
实际含义:对于任意函数 f(n)O(n) ,总存在函数 h(n)O(n2) ,使得 n2+f(n)=h(n)
用途: 如果有很长的“等式链”,第一个就等于最后一个(只能从左到右,因为 O 是非对称的)

Ω 符号

集合定义

Ω(g(n))={f(n):c>0,n0>0,使n>n00cg(n)f(n)}

例: n=Ω(lgn)
直观理解: 对于充分大的 n n 至少是 Ω(lgn) 的常数倍。

Θ 符号

Θ(g(n))=Ω(g(n))O(g(n))

例:
n2=Θ(n2)
n2+O(n)=Θ(n2)

oω 符号

更“严格的” O Ω ,不等式需要对所有的 c 成立,而不仅仅是一个特定的c

o(g(n))={f(n):c>0,n0>0,使n>n0,0f(n)cg(n)}
ω(g(n))={f(n):c>0,n0>0,使n>n0,0cg(n)f(n)}

在这种情况下, n0 依赖于c

例:
2n2=O(n3)
12n2=Θ(n2)o(n2)ω(n2)

类比

O Ω Θ o ω
= < >

解递归式

至今为止,求解递归式还没有一种通用的方法。

代换法

  1. 猜出解的形式( n2 / n3 )
  2. 通过数学归纳法验证
  3. 求解常数系数

例:
T(n)=4T(n2)+n
[T(1)=Θ(1)]
观察:由 T(n)=4T(n2) 可知(忽略 n ),当 n 翻倍时, T(n) 会变为原来的4倍。
猜想 Θ(n2) (直接证明 Θ(n2) 很难,先证明 Θ(n3)

证明 T(n)=O(n3)

  • 猜想: T(n)=O(n3)
  • 假设: k<n 时, T(k)ck3
    注意:代换法中不能使用 O 符号,因此需要用常数 c 来展开

    • 原因(较高层次):如果有一个有限项的大 O 关系序列,例如 n2=O(n3)=O(n4)=O(n4) ,由传递性可知 n2=O(n4) ,但如果大 O 关系序列是无限的,那么第一项不一定等于最后一项
    • 例:假如想证明 n=O(1) (这显然是不对的,否则所有算法都将是常数复杂度),但却可以通过数学归纳法证明,如下:

      • 1=O(1)
      • 假设 n1=O(1)
      • 由于 n=(n1)+1 ,由假设, n1=O(1) ,且已知 1=O(1) ,所以总体是 O(1)
    • 错误原因:证明过程中 O(1) 所代表的常数是变化的,每次 O(1) O(1) 相加,都可能把 O(1) 加倍,如果是常数次的加倍,那么最终结果仍然是 O(1) ,但如果是n次加倍,结果将从 O(1) 变为 O(n)

    • 结论:不能在 O 符号上进行归纳,代换法中需要用常数 c 来展开(保证不会在归纳过程中发生变化)
  • 推导
    T(n)=4T(n2)+n4c(n2)3+n=12cn3+n=cn3(12cn3n)cn3(if12cn3n0)c1,n1
  • 最基本的情况: T(1)=Θ(1)c13 ,当 cT(1)
  • 可知, T(n)=O(n3) ,但这并不是一个严格的上界,严格的上界还有可能是 O(n2)

证明 T(n)=O(n2)

  • 猜想: T(n)=O(n2)
  • 假设: k<n 时, T(k)ck2
  • 推导(仿照上面的过程)
    T(n)=4T(n2)+n4c(n2)2+n=cn2+n=cn2(n)cn2(if(n)0)(n)
改进归纳假设
  • 假设当 k<n T(n)c1k2c2k
  • 推导
    T(n)=4T(n2)+n4(c1(n2)2c2(n2))+n=c1n2+(12c2)n=c1n2c2n(1+c2)nc1n2c2n(if(c21)0)
  • 最基本的情况: T(1)c1c2 ,由于 T(1)=Θ(1) ,是一个常数,因此需要 c1T(1)+c2

递归树法

例: T(n)=T(n4)+T(n2)+n2

点赞