最大子列和問題


問題陳述:

  給定N個整數的序列{A1, A2, ... , AN},求函數ƒ(i, j) = max{0, Ai + Ai+1 + ... + Aj}(1<=i<j<=N)的最大值。

 

問題分析:

  求給定數列的最大子列和。

 

算法設計:

算法1:計算每個子列的和

時間復雜度: T(N) = O(N2)

 1 int MaxSubSeqSum(int arr[], int n) {
 2     int i, j, currentSum, maxSum = 0;
 3     for(i=0; i<N-1; i++) { /* i是子列左端的位置 */
 4         currentSum = 0; /* currentSum是從A[i]到A[j]的子列和 */
 5         for(j=i; j<N; j++) { /* j是子列右端位置 */
 6             currentSum += arr[j];
 7             if(currentSum > maxSum){
 8                 maxSum = currentSum; //更新maxSum
 9             }
10         }
11     }
12     return maxSum;
13 }

 

算法2:遞歸 分而治之

將數列分為兩部分,分別求出左右兩側的最大子數列,再求出跨越分界線的最大子數列,比較三者最大值即為所求的最大子數列。

時間復雜度: T(N) = O(NlogN)

 1 int MaxSubSeqSum(int arr[], int left, int right) {
 2     if(left == right){
 3         if(arr[left] > 0){
 4             return arr[left];
 5         }else {
 6             return 0;
 7         }
 8     }
 9 
10     int center = (left + right) / 2;
11     int leftMaxSum = MaxSubSeqSum(arr, left, center); /* 分界線左側最大子數列 */
12     int rigthMaxSum = MaxSubSeqSum(arr, center+1, right); /* 分界線右側最大子數列 */
13 
14     /* 以分界線往左求最大子數列 */
15     int leftBorderSum = 0, maxLeftBorderSum = 0;
16     for(int i=center; i>=left; i--) {
17         leftBorderSum += arr[i];
18         if(leftBorderSum > maxLeftBorderSum){
19             maxLeftBorderSum = leftBorderSum;
20         }
21     }
22 
23     /* 以分界線往右求最大子數列 */
24     int rightBorderSum = 0, maxRightBorderSum = 0;
25     for(int j=center+1; j<=right; j++) {
26         rightBorderSum += arr[j];
27         if(rightBorderSum > maxRightBorderSum) {
28             maxRightBorderSum = rightBorderSum;
29         }
30     }
31 
32     /* 跨越分界線最大子數列和 */
33     int maxBorderSum = maxLeftBorderSum + maxRightBorderSum;
34 
35     return maxSum(leftMaxSum, rigthMaxSum, maxBorderSum);
36 }
37 
38 /*
39 **  返回a, b, c三者最大值
40 */
41 int maxSum(int a, int b, int c){
42     if(a > b) {
43         a = b;
44     }
45     if(a > c) {
46         return a;
47     }else {
48         return c;
49     }
50 }

時間復雜度計算:

T(N) = 2 * T(N/2) + cN

   = 22 * T(N/22) + c2N

   = 2k * T(N/2k) + ckN 其中 N/2k = 1

        = N * T(1) + cNlog2N

   = O(NlogN)

 

算法3:在線處理(每輸入一個數據就進行即時處理)

時間復雜度: T(N) = O(N)

 1 int MaxSubSeqSum(int arr[], int n) {
 2     int currentSum, maxSum;
 3     currentSum = maxSum = 0;
 4     for(int i=0; i<n; i++) {
 5         currentSum += arr[i];  /* 向右累加 */
 6         if(currentSum > maxSum) {  /* 發現更大值 更新最大值 */
 7             maxSum = currentSum;
 8         }else if(currentSum < 0){  /* 如果當前子列為負 舍棄 置零 */
 9             currentSum = 0;
10         }
11     }
12     return maxSum;
13 }

 

參考資料:浙江大學數據結構

 

轉載請注明出處:http://www.cnblogs.com/michaelwong/p/4292936.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM