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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

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

最大字數組問題

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

?

暴力破解法

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

問題變換

為了方便我們處理,我們把每個數組的值變為股票的凈增量。這個時候,最佳解法就變成了求一個數組的最大字數組:

?

使用分治策略的求解法

我們可以認為,我們要尋找子數組array[start,end]的最大字數組分三種情況:

  • 最大字數組在左半部分
  • 最大字數組在右半部分
  • 最大字數組起點在左半部分,終點在右半部分

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

如圖:

?

那么我們給出解這個問題的思路:

FindMaxCrossingSubArray(array,start,end)mid=(start+end)/2從mid開始向左找,找到以mid為終點的最大字數組為array[max-left,min]從mid開始向右找,找到以mid為起點的最大字數組array[min,max-right]跨越mid的最大字數組為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個中的最大字數組

分治算法分析

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

代碼實現

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#實現了下,托管在了github上

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。