題目描述:給定義陣列a,長度為n,找出陣列a中的最大子陣列,例如陣列a=,則最大子陣列為。
使用分治策略的求解方法:假定我們要尋找子陣列a[low...high]的最大子陣列,使用分治法意味著我們要將子陣列劃分為兩個規模盡可能相等的子陣列。也就是說,找到子陣列的**位置,比如mid,然後求解兩個子陣列a[low...mid]和a[mid + 1...high]。所以可以知道,a[low...high]的任何連續子陣列a[i...j]所處的位置必然是三種情況之一:
1)完全位於子陣列a[low...mid]中, 因此low<=i<=j<=mid;
2)完全位於子陣列a[mid + 1...high]中,因此mid<=i<=j<=high;
3)跨越了中點,因此low<=i<=mid
實際上,a[low...high]的乙個最大子陣列必然是以上三種情況中的所有子陣列中和的最大者。所以,我們可以遞迴地求解a[low...mid]和a[mid + 1...high]的最大字陣列,然後在三者中選取和最大者。
int find_max_crossing_subarray(int a, int low, int mid, int high)
}int right_sum = -0xff;
sum = 0;
for (int j = mid + 1; j <= high; j ++)
}return left_sum + right_sum;
}
有了乙個線型時間的find_max_crossing_subarray()在手,我們就可以設計出求解最大子陣列問題的分治演算法**了:
int find_maximum_subarray(int a, int low, int high)
else
else if (right_sum >= left_sum && right_sum >= cross_sum)
else
}}
建立乙個遞迴式來描述遞迴過程find_maximum_subarray( )執行時間, 用t(n)表示find_maximum_subarray( )求解n個元素的最大字陣列的執行時間。因為前8行均為常量時間,所以t(1) = o(1). 第9和第10行給總的執行時間增加了2t(n/2)。第11行呼叫find_max_crossing_subarray( )花費o(n)的時間。因此對於遞迴情況,我們有:
t(n) = 2t(n/2) + o(n);
所以我們可以得到find_maximum_subarray( )的執行時間t(n)的遞迴式:
t(n) = o(1)n = 1
t(n) = 2t(n/2) + o(n)
n > 1
所以時間複雜度為o(nlg n);
#include using namespace std;
int find_max_crossing_subarray(int a, int low, int mid, int high)
}int right_sum = -0xff;
sum = 0;
for (int j = mid + 1; j <= high; j ++)
}return left_sum + right_sum;
}int find_maximum_subarray(int a, int low, int high)
else
else if (right_sum >= left_sum && right_sum >= cross_sum)
else
}}int main()
cout<<"最大子串行的和為:"<
演算法導論 分治演算法求最大子陣列
問題描述 求乙個陣列中的連續子陣列,該連續子陣列的和的值最大。解決方法 具體求解思路 使用遞迴。先將原陣列劃分為兩個陣列,不斷分治劃分,到最小 即low high 求此時的乙個小陣列的最大左子陣列與最大右子陣列以及cross mid.取最大值做為該小陣列的最大子陣列,不斷遞迴。如下 在這裡插入 片 ...
演算法導論 最大子陣列
之前都在準備考試,寒假還是繼續學習。除了家裡打掃衛生,似乎也確實沒什麼事。多看書,多寫 總能提高的。堅持。這次學到了函式返回值可以是乙個結構體,當我們要返回多個值的時候,就可以返回結構體。還有就是對分治法有了更深的認識。include typedef struct op op findmaxcros...
最大子陣列(分治法)
尋找a low,high 中的最大連續子陣列a i,j mid low high 2,欲求的最大連續子陣列出現的位置 1 出現在a low,mid 中 即 low i j mid 2 出現在a mid 1,high 中,即 mid 3 跨越了mid位置,出現在a low,high 中,即 low i...