演算法導論在分治策略一章中提到了最大子陣列和問題,我用c++實現了一下,還是挺簡單的,只不過要return最大子陣列的起始下標、結束下標和最大子陣列和這三個數有點麻煩,如要使用引用的話,因為要遞迴傳值所以不好實現,乙個可行的辦法是使用陣列,將這三個值放在陣列中傳遞。lz這裡並沒有寫這一過程。
分治演算法找最大子陣列和將情況分成三種:
1.最大和陣列在中間元素左側;
2.最大和子陣列在中間元素右側;
3.最大和子陣列跨越中間元素;
前兩個問題的子問題仍是最大子陣列問題,只是規模更小,於是我們剩下的全部工作就是尋找跨越中間元素的最大子陣列。然後在三種情況下選擇和最大者。
**如下:
1 #include 2using
namespace
std;34
int find_max_crossing_subarray(int a, int low, int mid, int high) //處理
最大子陣列在中間元素兩側情況521
}2223for(int i = mid + 1; i <= high; ++ i) //
找中間元素右側最大子陣列和
2431}32
33return left_sum + right_sum; //
兩側和相加再return回去34}
3536
int find_max_subarray(int a, int low, int
high)
3755}56
57int
main()58;
6061 cout << find_max_subarray(array, 0, 9) <6263
return0;
64 }
用分治法解決這一問題的時間複雜度為o(nlgn),還有非遞迴且時間線性的演算法。在網上找到乙個寫的比較好的程式,僅加了注釋列在下面:
1intmain()
214 printf("
enter each element:");
15for(j = 0; j < length ; j ++)
16 scanf("
%d",ip+j);
1718 max =int_min;
19for(sum = j = 0; j < length; j ++) //
sum初始為0,即預設陣列中不全為負數。
2029
if(sum < 0)35}
36for(j = start1,sum = 0; sum != max; j ++) //
從最大子陣列第乙個元素開始,一直到實現最大子陣列的最大值時結束
37 sum += *(ip+j);
38 printf("
\nthe subsequence from %d to %d,max sum is %d\n
",start1,j-1
,max);
39return0;
40 }
若不考慮記錄最大子陣列的其實位置,則更加簡單,主要**僅10行,主要思想就是負數不加到已得到的最大數值中,一旦發現已得到的最大子陣列到當前元素不可能成為最大子陣列,就嘗試尋找新的最大子陣列。
1for(int i = 0; i < n; i ++) 2
11return max;
陣列最大子串行和問題
問題描述 最大子串行 給定一整數序列a1,a2,an 可能有負數 求a1 an的乙個子串行ai aj,使得ai到aj的和最大。例如 整數序列 2,11,4,13,5,2,5,3,12,9的最大子串行的和為 子串行起始下標為 結束下標為 複雜度 o n return 子串行最大和,start 為子串行...
最大子陣列問題
顧名思義,最大子陣列問題是求乙個陣列array中 和最大的非空連續子陣列 這樣的連續子陣列我們叫做最大子陣列,它的應用也有 很多,比如說找出時間序列中兩個時間節點使得這兩個時間節點對應的值的落差最大,如下圖 對於這類問題,通過求原始時間序列的一階差分得到序列array,此時求得array的最大子陣列...
最大子陣列問題
include include include typedef struct num num extern void displayarray const int a,const int n 顯示陣列元素值 extern void buildarray int a,const int n 陣列元素賦...