最大子陣列的兩種實現原始碼

2021-06-26 18:00:53 字數 1817 閱讀 6882

演算法導論講分治策略這一章提到了乙個經典的問題,求乙個陣列的非空連續子陣列的最大值,陣列的元素可正、可負、可為零。

方法一:暴力求解法

簡單嘗試陣列每對值的組合求出最小值,時間複雜度o(n2)。

方法二:分治策略

時間複雜度o(nlgn)。將陣列劃分為兩個規模盡量相等的子陣列求解。比如找到子陣列的**位置mid,然後考慮求解兩個規模盡量相等的子陣列a[low...mid]和a[mid+1, high]。那麼a[low, high]的任何連續子陣列a[i,j]所處位置必然是三種情況之一:

1.完全位於a[low...mid]中;

2.完全位於a[mid+1, high]中;

3.跨越了中點。

1,2兩種情況可以可以遞迴實現,因此剩下的工作就是尋找跨越中點的最大子陣列,然後在三種情況中選最大者。

原始碼如下:

#include #include #include using namespace std;

struct subarray

;subarray findcrossarray(double dall, int low, int mid, int high)

} sum = 0;

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

struct subarray sa;

sa.low = max_left;

sa.high = max_right;

sa.sum = left_sum + right_sum;

return sa;

}subarray findmaximumsubarray(double dall, int low, int high)//遞迴傳參

else }

void main()

struct subarray result;

result = findmaximumsubarray(dallnum, 0, --i);

cout << result.low << " " << result.high << " " << result.sum << endl;

}

方法三:動態規劃

時間複雜度o(n)。從陣列左邊界開始,從左至右處理,記錄到目前為止已經處理過的最大子陣列。若已經a[0,j]的最大子陣列,則a[0,j+1]的最大子陣列要麼是a[0,j]的最大子陣列要麼是某個子陣列a[i,j+1]。

#include #include #include using namespace std;

struct subarray

;subarray findmaxsubarray(double dallnum, int nlength)

else//若前面最大子陣列之和小於0,則丟棄從當前開始,必須保證陣列有正才能這麼幹

if (b >= sum)

}maxarray.start = start;

maxarray.end = end;

maxarray.sum = sum;

return maxarray;

}void main()

struct subarray result;

result = findmaxsubarray(dallnum, --i);

cout << result.start << " " << result.end << " " << result.sum << endl;

}

最大子段和的兩種解法

1.貪心和動態規劃 實質一樣。前面和sum i 1 0sum 0 sumi 1 0就丟掉,然後加上a ia i ai 就是以a ia i ai 結尾的最大子段和。2.分治法。遞迴到l r l rl r時,顯然最大子段和是a ia i ai 對於區間 l,r l,r l,r 我們需要維護4個變數。1....

解決最大子陣列之和的兩種方法

自己碼了一遍這個演算法,然後網上找了下題目分析。發現了更好的解法 解決最大子陣列之和的三種方法,在此記錄一篇簡述心得。拿到題目自己理解的有誤,一直在想怎麼一邊計算和一邊記錄 start end 索引。其是題目沒有這個要求。因為最大子陣列 startindex 和 endindex 不確定,所以肯定需...

hdu1559,1081最大子矩陣和的兩種題型

最大子矩陣是一種典型的dp問題。某種程度上說是最大連續子串行和問題的擴充套件。這是最常見的最大子矩陣問題的體型。簡單的解決方案就是把列累加,遍歷任意兩行的累加值的差值,然後就轉換成了普通的最大連續子串行和問題。從而將二維問題轉換為一維。時間複雜度較高為o n 3 include include in...