高级算法日记7:专题

来源:互联网 发布:java枚举单例模式 编辑:程序博客网 时间:2024/05/22 01:46

专题

作者:相国大人

联系:sunxiangguodut@qq.com

版权所有,禁止转载

  • 专题
    • 专题一时间复杂度分析
      • 1 普通复杂度函数的增长
      • 2 递归与分治的复杂度主定理
    • 专题二求解迷宫问题
    • 专题三分治法深入
      • 1 二元搜索问题
      • 2 both max and min
      • 3 dominating numbers
      • 4 max sum two
    • 专题四线性规划
    • 专题五贪心算法
    • 专题六中位数和顺序统计量
    • 专题七散列表
    • 专题八红黑树
    • 专题九斐波那契堆wenti
    • 专题十van Emde Boas树
    • 专题十一 网络流
    • 专题十二字符串问题
    • 专题十三外排序

1. 专题一:时间复杂度分析

1.1 普通复杂度:函数的增长

Θ记号:

Θ(g(n))={f(n):c1,c2n0,使nn0,0c1g(n)f(n)c2g(n)}

Ω记号:

Ω(g(n))={f(n):cn0,使nn0,0cg(n)f(n)}

O记号:

O(g(n))={f(n):cn0,使nn0,0f(n)cg(n)}
这里写图片描述

1.2 递归与分治的复杂度:主定理

主定理:

对于T(n)=aT(n/b)+f(n),其中a1,b>1是常数,我们将n/b解释为n/bn/b,则T(n)有如下的渐进界:

  • 若对于某个常数ε>0,有f(n)=O(nlogbaε),则T(n)=Θ(nlogba)
  • f(n)=Θ(nlogba),则T(n)=Θ(nlogbalgn)=Θ(f(n)lgn)
  • 若对某个常数ε>0,有f(n)=Ω(nlogba+ε),且对某个常数c<1和所有足够大的n有af(n/b)cf(n),则T(n)=Θ(f(n))

练习:

T(n)=9T(n/3)+nlgn

T(n)=T(2n/3)+1

T(n)=2T(n/2)+n

T(n)=3T(n/2)+n2lgn

答案:

Θ(n2),也可以写成O(n2)

Θ(lgn)

Θ(nlgn)

Θ(n2lgn)

回顾:堆的维护

def max_heapify(A,current_root):  largest=max(current_root.left,current_root,current_root.right)  if largest is not current_root:    swap(largest,current_root)    max_heapify(A,largest)

这段代码的复杂度是多少?

T(n)=T(n/2)+O(1)

根据主定理得到复杂度为O(lgn)

因此,在优先队列中,如果采用堆来存储,那么函数extract_min()的复杂度为O(lgn)

因此,堆排序的复杂度为O(nlgn)

判断下面代码的时间复杂度:

快速排序:

def partition(A,p,r)    x=A[r]    i=p-1    for j=p to r-1        if A[j]<=x            i=i+1            swap(A[i],A[j])    swap(A[i+1],A[r])    return i+1def quick_sort(A,p,r)    q=partition(A,p,r)    quick_sort(A,p,q-1)    quick_sort(A,q+1,r)

显然,第一个函数的代码时间复杂度为A[p...r]的长度,即O(n),所以quick_sort()的时间复杂度为:

T(n)=2T(n/2)+O(n)

根据主定理,T(n)=Θ(nlgn)

归并排序:

def merge_sort(A[p...r])    mid=(p+r)/2    merge_sort(A[p...mid])    merge_sort(A[mid+1...r])    merge(A[p...mid],A[mid+1...r],C[p...r])    A[p...r]=C[p...r]

merge的复杂度为O(m1+m2)

所以整体的复杂度为

T(n)=2T(n/2)+O(n)

根据主定理,T(n)=Θ(nlgn)

确定下面这个式子的复杂度:

T(n)=2T(n)+lgn

解答:

n=2k,并带入原式得:

T(2k)=2T(2k/2)+k

我们令S(k)=T(2k),则有:

S(k)=2S(k/2)+k

根据主定理,有S(k)=Θ(klgk)

因为n=2k所以k=lgn,于是得到T(n)=T(2k)=S(k)=Θ(klgk)=Θ(lgnlglgn)

2. 专题二:求解迷宫问题

待续未完

3. 专题三:分治法深入

分治法是将一个规模为n的问题分解为若干个规模小一些的子问题,然后找出这些字问题或者一部分子问题的解并由此得到原问题的解。在解决这些子问题时,分治法要求用同样的方法递归解出。也就是说,我们必须能把这些子问题用同样的方式再分为更小的问题直至问题的规模小到可以直接解出。这个不断分解的过程看起来很复杂,但用递归的算法表达出来却往往简洁明了。通常,分治法只要讲明三件事即可:

  • Bottom case:对于足够小的输入规模,如何直接解出
  • Divide:如何将一个规模为n的输入分为整数个规模小一些的字问题
  • Conquer:如何从子问题的解中获得原规模为n的解

3.1 二元搜索问题

假定要在一个已经排好序的数组A[1...n]中查找一个数是否等于x,如果有A[i]=x,则报告序号i,否则报告none,我们可以采用以下的算法:

def binary_search(A,p,r,x)    if p>r:        return none    mid=(p+r)/2    if A[mid]=x:        return mid    elif x<A[mid]:        binary_search(A,p,mid-1,x)    else:        binary_search(A,mid+1,r,x)

(想一想,复杂度是多少?)

3.2 both max and min

Given n numbers stored in A[1..n], we wish to design a divide-and-conquer algorithm that finds both the maximum number and the minimum number in this array.

这里写图片描述

时间复杂度T(n)=2T(n/2)+O(1)

3.3 dominating numbers

这里写图片描述
这里写图片描述
这里写图片描述

3.4 max sum two

这里写图片描述
这里写图片描述
这里写图片描述

4. 专题四:线性规划

待续未完

5. 专题五:贪心算法

待续未完

6. 专题六:中位数和顺序统计量

待续未完

7. 专题七:散列表

待续未完

8. 专题八:红黑树

待续未完

9. 专题九:斐波那契堆wenti

待续未完

10. 专题十:van Emde Boas树

待续未完

11. 专题十一: 网络流

待续未完

12. 专题十二:字符串问题

待续未完

13. 专题十三:外排序

待续未完

原创粉丝点击