一 寫在開頭算法
何爲最大子序列和問題?最大子序列和問題能夠描述以下:給定一個整數序列A1, A2, ..., AN(可能有負數),試求其存在的一子序列AI, AJ, ...,AM所能達到的最大值(I, J,...,M不必定是相鄰的,只要知足I <= J <= ... <= M便可)(爲方便起見,若是全部整數均爲負數,則其最大子序列和爲0)。數據結構
1.1 本文內容this
求解最大子序列和的幾種算法。spa
二 算法一code
算法一是至關直觀的枚舉算法,其時間複雜度爲O(N ^ 3)。主要由算法中的三重for循環達成。其實現以下:blog
1 int 2 MaxSubsequenceSum(const int a[], int n) 3 { 4 int thisSum, maxSum, i, j, k; 5 6 maxSum = 0; 7 for (i = 0; i < n; i++) 8 for (j = i; j < n; j++) 9 { 10 thisSum = 0; 11 for (k = i; k <= j; k++) 12 thisSum += a[k]; 13 14 if (thisSum > maxSum) 15 maxSum = thisSum; 16 } 17 return maxSum; 18 }
三 算法二遞歸
算法二在算法一的基礎上去掉了第三重for循環,所以其時間複雜度爲O(N ^ 2)。其實現以下:for循環
1 int 2 MaxSubsequenceSum(const int a[], int n) 3 { 4 int thisSum, maxSum, i, j; 5 6 maxSum = 0; 7 for (i = 0; i < n; i++) 8 { 9 thisSum = 0; 10 for (j = i; j < n; j++) 11 { 12 thisSum += a[j]; 13 if (thisSum > maxSum) 14 maxSum = thisSum; 15 } 16 } 17 }
四 算法三class
算法三是個遞歸算法。其每次都將區間一分爲二,而後再分別對左右區間遞歸地進行求解。由於,擁有最大和的子序列要麼徹底處於左區間,要麼徹底處於右區間,要麼就是左區間的子序列加上右區間的子序列以拼湊成一個和更大的子序列。該算法時間複雜度爲O(NlogN),其實現以下:基礎
1 int 2 MaxSubsequenceSum(const int a[], int left, int right) 3 { 4 int maxLeftSum, maxRightSum; 5 int maxLeftBorderSum, maxRightBorderSum; 6 int leftBorderSum, rightBorderSum; 7 int center, i; 8 9 /* base case */ 10 if (left == right) 11 if (a[left] > 0) 12 return a[left]; 13 else 14 return 0; 15 16 center = (left + right) / 2; 17 maxLeftSum = MaxSequenceSum(a, left, center); 18 maxRightSum = MaxSequenceSum(a, center + 1, right); 19 20 maxLeftBorderSum = leftBorderSum = 0; 21 for (i = center; i >= left; i--) 22 { 23 leftBorderSum += a[i]; 24 if (leftBorderSum > maxLeftBorderSum) 25 maxLeftBorderSum = leftBorderSum; 26 } 27 28 maxRightBorderSum = rightBorderSum = 0; 29 for (i = center + 1; i <= right; i++) 30 { 31 rightBorderSum += a[i]; 32 if (rightBorderSum > maxRightBorderSum) 33 maxRightBorderSum = rightBorderSum; 34 } 35 36 return MAX3(maxLeftSum, maxRightSum, maxLeftSum + maxRightSum); 37 }
五 算法四
算法四比較巧妙,並且時間複雜度只有O(N),優於上面的三種算法,其實現以下:
1 int 2 MaxSubsequenceSum(const int a[], int n) 3 { 4 int thisSum, maxSum, i; 5 6 thisSum = maxSum = 0; 7 for (i = 0; i < n; i++) 8 { 9 thisSum += a[i]; 10 if (thisSum > maxSum) 11 maxSum = thisSum; 12 else if (thisSum < 0) 13 thisSum = 0; 14 } 15 return maxSum; 16 }
六 參考資料
1. 《數據結構與算法分析:C語言描述》