算法(2)-递归式时间复杂度求解与分治法

要点

  • 递归式T(n)求解
    • 代换法*
    • 迭代法*
    • 递归树
    • 主定理 Master (core)
  • 分治策略
    • Insert Sort 插入排序 VS Merge Sort 归并排序
    • 最大子数组
    • 矩阵Strassen乘法(*)
    • 多数问题 Majority Problem

复习

  • 输入规模: 假设输入了一个大小为n的十进制数, 在计算机中所占用的x位, 即2^x = n
    因此, 占用内存位数x (单位: bit) = lgn (bit)
    因此, 我们一般都说大小为n的十进制数的在计算机中表现为C*lgn个bit 输入规模 (C = Constant)

递归式求解

  • 代换法: 猜; 猜了以后用数学归纳法证明;
    • 猜测T(n) = nlgn + n;
    • 假设T(k) = k*logk + k; (k<n就可以)
    • 验证T(n) 状况, 代入T(n) = 2T(n/2)+n来求解;
    • 例题2: Tn=T(n/2)up+T(n/2)down +1 (为什么这里不能丢掉1? 因为下面的要求!)
    • 避免陷阱: 数学归纳法的原理是推理链条, 小项目会累积, 必须严格证明, 不能丢掉低阶级项目;
    • 变量替换: sqrt(n) 用m替换; 形式上更容易求解;
    • 对更小的值做更强的假设;
  • 迭代法
    • 不断地把递归式子展开, 对各个展开项目求和, 迭代法对代数能力要求较高;
    • 难点: 迭代次数求解, 级数求和;
    • 弄明白一个除以2, 一个加1的关系;
  • 递归树方法
  • 主方法
    • T(n) = a*T(n/b) + f(n);
    • 注意n*logn和n^1.0001对比仍然是后者大

分治算法

备注: 实际C语言中数组下标为a[0]~a[length-1], pseudo code里面我们按照日常习惯, 从1~length

注: 插入排序不是分治算法, 只是这里一起写, 和merge-sort做比较.

Insert-Sort()
for i = 2 to A.length
  key = A[i]    //insert key to sequence A[1~i-1]
  j = i-1
  while j>0 && A[j]>key
    A[j+1] = A[j]    //把值向后移动一位
    j--
  A[j+1] = key    //当发生A[j]<=key的时候, 让key的值占据A[j+1]位置, 注意A[j+2]已经安全存好了原先A[j+1]的值

最典型的Divide and Conquer: Merge Sort

//@p: prior;
//@r: rear;
Merge-Sort(A, p, r)
if p<r    //when p == r, the following lines will not execute
  q = floor((p+r)/2)
  Merge-Sort(A, p, q)
  Merge-Sort(A, q+1, r)
  Merge(A, p, q, r)
Merge(A, p, q, r) {
n1 = q-p+1
n2 = r-q
let L[n1+1] and R[n2+1] be new arrays
for (i = 1 to n1) 
    L[i] = A[p-1+i]
for (j = 1 to n2)
    R[j] = A[q+j] 
L[n1+1] = 99999    //代表无穷大的哨兵牌, 最后不输出
L[n2+2] = 99999
i = 1, j = 1
for (k=p to r)
    if (L[i]<R[j])
        A[k] = L[i]
        i++
    else 
        A[k] = R[j]
        j++
}

时间复杂度分析:
(1)写出递归式: T(n) = 2T(n/2)+Θ(n)
(2)使用主定理: 计算n^log(b下a上) = n = f(n) , 所以T(n) = nlgn

  • 最大子数组;
/*主算法: 找最大子数组*/
//low表示左边端点, high右侧端点, A是数组
Find-Maximum-SubArray(A, low, high)
if (low == high) 
    return (low, high, A[low])
mid = floor((low+high) / 2)  //下中位数
(left-low, left-high, left-sum) = Find-Maximum-SubArray(A, low, mid)
(right-low, right-high, right-sum) = Find-Maximum-SubArray(A, mid+1, high)  //记得是[mid+1, high] 左侧端点要mid+1
(cross-low, cross-high, cross-sum) = Find-Max-Crossing-SubArray(A, low, mid, high) 
if (left-sum>right-sum and left-sum>cross-sum) 
    return (left-low, left-high, left-sum)
else if (right-sum>left-sum and right-sum>cross-sum) 
    return (right-low, right-high, right-sum)
else 
    return (cross-low, cross-high, cross-sum) 
/*辅助算法: 找跨越中点数的最大子数组*/
Find-Max-Crossing-SubArray(A, low, mid, high) 
left-sum = -9999
sum = 0
for (i=mid; i>=low; i--)
    sum = sum+A[i]
    if (sum > left-sum)
        left-sum = sum
        max-left = i
right-sum = -9999
sum = 0
for (i=mid+1; i<=high; i+)
    sum = sum+A[i]
    if (sum > right-sum)
        right-sum = sum
        max-right = i
return (max-left, max-right, (left-sum+right-sum) )

时间复杂度分析: (分治类常用)
(1)写出递归式: T(n) = T(n/2) + T(n/2) + Θ(n) + Θ(1) = 2T(n/2) + Θ(n)
(2)使用主定理: n^(log(b下a上)) = n = f(n) , 所以T(n) = Θ(nlgn)

  • 多数问题;
  • 矩阵Strassen*

===========作业===========

  • majority
  • 3-4 助教题目
  • 上机题 做最大子数组(分治)
  • 递归的主定理的证明, 要搞明白怎么用怎么来的;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容