算法导论读书笔记 第4章 分治策略
?在第2章中,歸并排序算法使用了分治策略。即在分治策略中,遞歸地求解一個(gè)問(wèn)題,在每層遞歸中應(yīng)包含三個(gè)步驟:
? 分解(Divide)步驟將問(wèn)題畫分為一些子問(wèn)題,子問(wèn)題的形式與原問(wèn)題一樣,只是規(guī)模更小。
? 解決(Conquer)步驟遞歸地求解出子問(wèn)題。如果子問(wèn)題的規(guī)模足夠小,則停止遞歸,直接求解。
? 合并(Combine)步驟將子問(wèn)題的解組合成原問(wèn)題的解。
? 當(dāng)子問(wèn)題足夠大時(shí),需要遞歸求解時(shí),我們稱之為遞歸情況(recursive case)。當(dāng)子問(wèn)題變得足夠小,不需要在遞歸時(shí),此時(shí)已進(jìn)入基本情況(base case)。有時(shí),除了與原問(wèn)題形式完全一樣的規(guī)模更小的子問(wèn)題外,還需求解與原問(wèn)題不完全一樣的子問(wèn)題,但這種情況可以看做是合并步驟的一部分。本章中會(huì)看到兩個(gè)基于分治策略的算法。其中一個(gè)是求解最大子數(shù)組問(wèn)題,其輸入是一個(gè)數(shù)值數(shù)組,算法需要確定有最大和的連續(xù)子數(shù)組。
? 遞歸式
? 遞歸式是與分治法緊密相關(guān)的,因?yàn)檫f歸式子可以很自然地刻畫分治算法的運(yùn)行時(shí)間。一個(gè)遞歸時(shí)就是一個(gè)等式或不等式,它通過(guò)更小的輸入上的函數(shù)值來(lái)描述一個(gè)函數(shù)。用遞歸式描述MERGE-SORT過(guò)程的最壞運(yùn)行時(shí)間為T(n):
求解可得T(n) = O(nlgn)。
4.1 最大子數(shù)組問(wèn)題
? 最大子數(shù)組問(wèn)是指需找數(shù)組中和最大的非空連續(xù)子數(shù)組,稱這樣的子數(shù)組為最大子數(shù)組(maximum subarray)。如下圖數(shù)組A中,A[1.. 16]的最大子數(shù)組為A[8.. 11],其和為43。
? 最大子數(shù)組中只有包含負(fù)數(shù)時(shí)才有意義,如果所有數(shù)組元素都是非負(fù)的,最大子數(shù)組問(wèn)題沒(méi)有任何難度,以為整個(gè)數(shù)組的和可定是最大的。
? ?使用分治策略求解最大子數(shù)組問(wèn)題
??假定要尋找子數(shù)組A[low.. high]的最大子數(shù)組。使用分治策略意味著要將數(shù)組劃分為兩個(gè)規(guī)模盡量相等的子數(shù)組。即找到子數(shù)組的中央位置,比如mid,然后考慮求解兩個(gè)子數(shù)組A[low.. mid]和A[mid + 1.. high]。如下圖所示,A[low.. high]的任意連續(xù)子數(shù)組A[i.. j]所處的位置必然是如下三種情況之一:
? ? ?1 完全位于子數(shù)組A[low.. mid]中, 因此 low <= i <= j <= mid
? ? ?2 完全位于子數(shù)組A[mid + 1, high]中, 因此 mid < i <= j <= high
? ? ?3 跨越了中點(diǎn), 因此low <= i <= mid < j <=high
? ? ?因此,A[low.. high]的最大子數(shù)組所處的位置必然是這三種情況之一。通過(guò)調(diào)用FIND-MAX-CROSSING-SUBARRAY接受數(shù)組A和下標(biāo)low,mid和high為輸入,返回一個(gè)下標(biāo)元組劃定跨越中點(diǎn)的最大子數(shù)組的邊界,并返回最大子數(shù)組中的和。為代碼如下:(-INT_MAX表示負(fù)的無(wú)窮大)
Find-Max-Crossing-SUBARRAY(A, low, mid, high):left-sum = -INT_MAXsum = 0for i =mid downto low:sum = sum + A[i]if sum > left-sum:left-sum = summax-left = iright-sum = -INT_MAXsum = 0max-right = 0for j = mid + 1 to highsum = sum + A[j]if sum > right-sum:right-sum = summax-right = jreturn (max-left, max-right, left-sum + right-sum)
(由于偽代碼中返回值時(shí)有多個(gè)參數(shù),突然不知道用c/c++語(yǔ)言怎么實(shí)現(xiàn),故采用python語(yǔ)言實(shí)現(xiàn)。歡迎各位高手用c/c++語(yǔ)言實(shí)現(xiàn)該算法)采用python代碼實(shí)現(xiàn)的完整程序?yàn)?#xff1a;
def findMaxCrossingSubArray(A, low, mid, high):leftSum = -65536sum2 = 0maxLeft = 0for i in range(mid, low, -1):sum2 = sum2 + A[i]if sum2 > leftSum:leftSum = sum2maxLeft = irightSum = -65536sum2 = 0maxRight = 0for j in range(mid+1, high):sum2 = sum2 + A[j]if sum2 > rightSum:rightSum = sum2maxRight = jreturn maxLeft, maxRight, leftSum + rightSumFIND-MAX-CROSSING-SUBARRAY的運(yùn)行時(shí)間為線性時(shí)間,則最大子數(shù)組問(wèn)題的分治法算法的偽代碼如下: FIND-MAXIMUM-SUBARRAY(A, low, high) 1 if high == low 2 return(low, high, A[low]) 3 else mid = (low + high) / 2 4 (left-low, left-high, left-sum) = FIND-MAXIMUM-SUBARRAY(A, low, mid) 5 (right-low, right-high, right-sum) = FIIND-MAXIMUM-SUBARRAY(A, mid+1, high) 6 (cross-low, cross-high, cross-sum) = FIND-MAXMUM-SUBARRAY(A, low, mid, higt) 7 if left-sum>=right-sum and left-sum >= cross-num 8 return (left-low, left-high, left-sum) 9 elseif right-sum >= left-sum and rigth-sum >=cross-sum 10 return(right-low, right-high, right-sum) 11 else return (cross-low, cross-high, cross-sum) 初始調(diào)用FIND-MAXIMUM-SUBARRAY(A, 1, A.Length)會(huì)求出A[1.. n]的最大子數(shù)組。pyhton語(yǔ)言實(shí)現(xiàn)的完整程序?yàn)?#xff1a;
def findMaximumSubArrary(A, low, high):if high == low:return low, high, A[low]else:mid = (low + high) / 2leftLow, leftHigh, leftSum = findMaximumSubArrary(A, low, mid)rightLow, rightHigh, rightSum = findMaximumSubArrary(A, mid + 1, high)crossLow, crossHigh, crossSum = findMaxCrossingSubArray(A, low, mid, high)if leftSum>=rightSum and leftSum>=crossSum:return leftLow, leftHigh, leftSumelif rightSum>=leftSum and rightSum>=crossSum:return rightLow, rightHigh, rightSumelse:return crossLow, crossHigh, crossSum尋找最大子數(shù)組的遞歸式與歸并排序的遞歸式是相同的,故算法時(shí)間復(fù)雜度為O(nlgn)。 與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的算法导论读书笔记 第4章 分治策略的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 算法导论学习笔记 第2章 算法基础
- 下一篇: 算法导论学习笔记 第6章 堆排序