CHAPTER5 分治法

本文来自我的个人博客 https://www.zhangshenghai.com/posts/57540/

分治法是将一个复杂的问题分成一些规模较小而结构与原问题相似的子问题,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。

分治法在每一层的递归上都有三个步骤:

  • 分解(Divided):将原问题分解成一系列子问题。
  • 解决(Conquer):递归地解各子问题。
  • 合并(Combine):将子问题的结果合并成原问题的解。

假设我们将原问题分解成a个子问题,每一个的大小是原问题的1/b。如果分解和合并的时间各为D(n)和C(n),则可得到递归式:

合并排序(Merge Sort)

当合并排序的运行时间如下分解:

  • 分解:仅计算出子数组的中间位置,需要常量时间,故D(n) = \Theta(1)
  • 解决:递归地解两个规模为n/2的子问题,时间为2T(n/2)
  • 合并:在一个含有n个元素的子数组上,MERGE过程的运行时间为\Theta(n),则C(n) = \Theta(n)

因此,合并排序的最坏运行时间T(n)的递归表示是:

由之前第一章介绍的主定理,我们可以得到T(n) = \Theta(nlgn),这里的lgn代表log_2n。同样,我们也可以通过递归树得到相同的答案。

最大子数组问题(Maximum Subarray Problem)

对于一个具有连续连续值的数组A,寻找A的和最大的非空连续子数组,我们称这样的连续子数组为最大子数组。例如,对于下图的数组,A[1...16]的最大子数组是A[8...11],其和为43。在实际的例子中可表示在第8天买入股票,并在第11天卖出,获得的收益为43美元。

使用分治法可以求解最大子数组问题。首先找到数组的中间点,将数组分为左右两个数组,那么最大子数组可能存在于下列三种情况之一:

  • 完全位于左边的数组中。
  • 完全位于右边的数组中。
  • 跨越了左右两个数组。

对于前两种情况,使用同样的方式递归地划分为规模最小的子数组求解即可。对于第三种情况,我们采用的算法是从中间点向两边遍历,分别求出两边的最大子数组,然后将左右两边的子数组相加即为跨越中点的最大子数组。

下面给出算法的伪代码:

对FIND-MAXIMUM-SUBARRAY算法的运行时间进行分析:

首先计算出子数组的中间位置,需要常量时间\Theta(1),然后递归地解两个规模为n/2的子问题,时间为2T(n/2),调用FIND-MAX-CROSSING-SUBARRAY花费了\Theta(n)时间,则T(n) = \Theta(1) + 2T(n/2) + \Theta(n),用主方法或递归树求解此递归式可得T(n) = \Theta(nlgn)

斐波那契数列(Fibonacci Number)

对于斐波那契数,我们有F_0=0, F_1=1, F_n=F_{n-1}+F_{n-2}。利用分治策略,我们可以将斐波那契数列转换为矩阵乘幂的问题,如下图所示:

使用分治法,我们将矩阵递归地分解成两个相同的矩阵,再将这两个矩阵相乘即可。

T(n) = T(n/2)+O(1) = T(n)/4+2O(1) = ... = T(n/2^{logn})+O(logn)×O(1)

整数乘法(Integer Multiplication)

假设x, y分别为两个n-bit的整数,如果要将它们相乘,模拟使用手动乘法得到的时间复杂度是\Theta(n^2),考虑分治法。

x = (10^ma+b), y=(10^mc+d),如x=1234567890, m=5, a=12345, b=67890。那么x×y = (10^ma+b)(10^mc+d)= 10^{2m}ac+10^m(bc+ad)+bd,这里的时间复杂度T(n) = 4T(n/2)+O(n),使用主方法可得T(n) = O(n^2)

Anatolii, Karatsuba在1962年提出了一个只需要三次子乘法就可以完成运算的算法,其时间复杂度的递归表示为T(n) = 3T(n/2)+O(n),使用主方法可得T(n) = O(n^{lg3})

矩阵乘法(Matrix multiplication)

给定一个n维矩阵X和Y,计算Z=XY。我们可以使用分治法求解这个问题。

  • 分解:将X和Y分解为n/2维的矩阵。
  • 解决:使用8次矩阵乘法递归地将这些n/2维的矩阵相乘。
  • 合并:使用4次矩阵加法将矩阵合并。

下面给出一个例子:

1969年Strassen提出了一个只需要7次矩阵乘法就可以完成运算的算法,算法将原矩阵分为7个新的子矩阵如下图所示:

然后进行计算:

此算法的时间复杂度为T(n) = 7T(n/2)+\Theta(n^2)=O(n{log_27})=O(n^{2.81})

凸包问题(The Convex Hull Problem)

假设平面上有一系列点,过某些点作一个多边形,使这个多边形能把所有点都“包”起来,当这个多边形是凸多边形的时候,我们就叫它凸包,凸包问题就是求构成凸包的点,如下图所示。

使用蛮力法是最容易想到的,思路是由两点确定一条直线,如果剩余的点都在这条直线的同一侧,那么认为这两个点是构成凸包的点。蛮力法的时间复杂度为O(n^3)

下面我们介绍解决凸包问题的分治法,下面为具体步骤和图例:

  1. 将所有点放在二维坐标系里,那么横坐标最大的两个点p_1、p_n一定是凸包上的点(具体可以用反证法证明,这里不展开说)。直线p_1p_n将点集合分为了两部分,分别叫上包和下包。
  2. 对于上包,求距离直线p_1p_n最远的点,即下图中的p_{max}
  3. 作直线p_1p_{max}p_np_{max},把p_1p_{max}左侧的点当作上包,把p_np_{max}右侧的点也当作是上包。
  4. 重复步骤2、3。
  5. 对下包也做类似的操作。

分治法的时间复杂度为T(n) = 2T(n/2) + O(n) = O(nlogn)

三格骨牌问题(Tromino Tiling)

对于三格骨牌问题,同样可以用分治法求解,解决这个问题的思想是每次都将平板分成四块同等大小的子平板。

例如,在插入三格骨牌时,将平板分成四块,由于洞位于左上方的子平板,因此将三个骨牌放置为如图所示的位置,以确保四块子平板的大小相等。递归地进行这个过程即可得出结果。

最邻近点问题(Finding the Closest Pair of Points)

顾名思义,最邻近点问题即在平面点集中找出距离最近的两个点。使用时间复杂度为O(n^2)的蛮力法可以解决这个问题。

下面我们介绍解决这个问题的分治法,首先将点集划分为两个部分,然后递归地寻找最近的点,若找到最近的两个点之间的距离为\delta,则寻找是否存在分别属于两个部分的点之间的距离小于\delta,算法的时间复杂度为T(n) = O(n)+2T(n/2)+O(n)=O(nlgn)

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

推荐阅读更多精彩内容

  • 动态规划 111. 爬楼梯思路类似斐波那契数列注意考虑第 0 阶的特殊情况 272. 爬楼梯 II思路类似上题,只...
    6默默Welsh阅读 2,411评论 0 1
  • 贪心算法 贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上...
    fredal阅读 9,202评论 3 52
  • 麻省理工学院公开课:算法导论。B站地址,网易公开课也有对应的资源。https://www.bilibili.com...
    LuLuX阅读 1,633评论 0 1
  • 目录 零、主定理 零-零、利用数学方法求解递归式 一、归并排序*二、最大子数组问题2.1 问题描述2.2 使用分治...
    王侦阅读 1,802评论 0 3
  • “有些东西你注视它越久,你就会越来越陌生,这座城市,这条街道,街道上来来往往的人,你身边熟悉的人,你的亲人,甚至是...
    丫是老段阅读 356评论 0 1