日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【转】算法导论学习笔记 一 分治算法

發(fā)布時(shí)間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】算法导论学习笔记 一 分治算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

分治策略是一種常見的算法。在分治策略中,我們遞歸的求解一個(gè)問題,在每層遞歸中應(yīng)用如下三個(gè)步驟: 1. 分解,將問題分解成規(guī)模更小但解決方案相同的子問題 2. 解決,遞歸的求解子問題,如果子問題足夠小則停止遞歸,直接求解 3. 合并,將子問題的解組合成原問題的解

最大字?jǐn)?shù)組問題

給你一段股市的波動(dòng)圖,找到在什么時(shí)候買入,什么時(shí)候賣出能獲得最大的收益。

?

暴力破解法

我們很容易的想到一個(gè)包里破解法,就是把所有買入,賣出的組合列舉出來(lái)進(jìn)行對(duì)比,n天中取任意兩天作為買入日和賣出日,共有n*(n-1)/2種解法,因此這種解法的時(shí)間復(fù)雜度是O(n^2)。

問題變換

為了方便我們處理,我們把每個(gè)數(shù)組的值變?yōu)楣善钡膬粼隽俊_@個(gè)時(shí)候,最佳解法就變成了求一個(gè)數(shù)組的最大字?jǐn)?shù)組:

?

使用分治策略的求解法

我們可以認(rèn)為,我們要尋找子數(shù)組array[start,end]的最大字?jǐn)?shù)組分三種情況:

  • 最大字?jǐn)?shù)組在左半部分
  • 最大字?jǐn)?shù)組在右半部分
  • 最大字?jǐn)?shù)組起點(diǎn)在左半部分,終點(diǎn)在右半部分

對(duì)于前兩種情況,我們的求解方式和分解前是相同的,我們需要單獨(dú)處理第三種情況。

如圖:

?

那么我們給出解這個(gè)問題的思路:

FindMaxCrossingSubArray(array,start,end)mid=(start+end)/2從mid開始向左找,找到以mid為終點(diǎn)的最大字?jǐn)?shù)組為array[max-left,min]從mid開始向右找,找到以mid為起點(diǎn)的最大字?jǐn)?shù)組array[min,max-right]跨越mid的最大字?jǐn)?shù)組為array[max-left,max-right]max-leftchild =FindMaxCrossingSubArray(array,start,mid)max-rightchild =FindMaxCrossingSubArray(array,min,end)return max-leftchild,max-rightchild,array[max-left,max-right] 3個(gè)中的最大字?jǐn)?shù)組

分治算法分析

這種方法我們需要遍歷的次數(shù)會(huì)比n^2少一些,時(shí)間復(fù)雜度為O(nlgn)

代碼實(shí)現(xiàn)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

public?int[] FindRecrusive(int[] array,?int?low,?int?high)

{

????Console.WriteLine("low {0}, high {1}", low, high);

?

????if?(low == high)

????{

????????return?new[] { low, high, array[low] };

????}

????int?mid = (low + high) / 2;

?

????int?leftmaxsum =?int.MinValue;

????int?currentleftsum = 0;

????int?leftmaxlocation = mid;

?

????for?(int?i = mid; i >= low; i--)

????{

????????currentleftsum += array[i];

????????if?(currentleftsum > leftmaxsum)

????????{

????????????leftmaxsum = currentleftsum;

????????????leftmaxlocation = i;

????????}

????}

?

????int?rightmaxsum = 0;

????int?currentrightsum = 0;

????int?rightmaxlocation = mid;

?

????for?(int?j = mid + 1; j <= high; j++)

????{

????????currentrightsum += array[j];

????????if?(currentrightsum > rightmaxsum)

????????{

????????????rightmaxsum = currentrightsum;

????????????rightmaxlocation = j;

????????}

????}

?

????int[] result =?new[] { leftmaxlocation, rightmaxlocation, leftmaxsum + rightmaxsum };

?

????int[] leftresult = FindRecrusive(array, 0, mid);

?

????if?(leftresult[2] > result[2])

????{

????????result = leftresult;

????}

?

????int[] rightresult = FindRecrusive(array, mid + 1, high);

????if?(rightresult[2] > result[2])

????{

????????result = rightresult;

????}

?

????return?result;

}

  

自己嘗試用C#實(shí)現(xiàn)了下,托管在了github上

總結(jié)

以上是生活随笔為你收集整理的【转】算法导论学习笔记 一 分治算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。