求解最大子序列和
tag: 數據結構與算法
最大子序列和問題:
給定序列A 1 , A 2 ,... A N , 求最大的子序列和。
例如 :
對于序列4, -3, 5, -2, -1, 2, 6, -2, 最大序列和為11(4 -3 + 5 - 2 - 1 + 2 + 6)
算法一:
利用兩個循環,第一個循環把序列遍歷一遍,第二個循環則從A i 累加到A N ,每加一次判斷一下是否大于之前的最大子序列和:
int maxSubsequenceSum1 (const int arr[], int n) {
int maxSum = 0;
int temp;
for (int i = 0; i < n; i++) {
temp = 0;
for (int j = i; j < n; j++) {
temp += arr[j];
if (temp > maxSum)
maxSum = temp;
}
}
return maxSum;
}
時間復雜度:O(n 2 )
算法二:
首先把序列從中間一分為二, 則最大子序列和的存在有三種情況:
-
全在左邊的子序列
-
全在右邊的子序列
-
處在中間
對于第一和第二種情況,只需要遞歸調用求解函數,對于第三種情況則要分別求出從中間出發,向左邊和向右邊各自的最大子序列和。
int max(int a, int b, int c) {
int max;
if (a > b)
max = a;
else
max = b;
if (c > max)
max = c;
return max;
}
int maxSubsequenceSum2 (const int arr[], int begin, int end) {
int maxLeftSum, maxRightSum, maxLeftCenterSum, maxRightCenterSum, center, temp;
if (begin >= end) {
if (arr[begin] > 0)
return arr[begin];
else
return 0;
}
center = (begin+end)/2;
maxLeftSum = maxSubsequenceSum2(arr, begin, center);
maxRightSum = maxSubsequenceSum2(arr, center+1, end);
maxLeftCenterSum = 0;
temp = 0;
for (int i = center; i >= begin; i--) {
temp += arr[i];
if (temp > maxLeftCenterSum)
maxLeftCenterSum = temp;
}
maxRightCenterSum = 0;
temp = 0;
for (int i = center+1; i <= end; i++) {
temp += arr[i];
if (temp > maxRightCenterSum)
maxRightCenterSum = temp;
}
return max(maxLeftSum, maxRightSum, (maxLeftCenterSum+maxRightCenterSum));
}
時間復雜度:O(nlogn)
算法三:
累加序列,若發現當前序列和大于之前最大序列和,則替換.若發現當前序列和小于0,則將當前序列和置換成0,相當于把前面的序列都舍棄掉.
int maxSubsequenceSum3(int arr[], int n) {
int tempSum = 0, maxSum = 0;
for (int i = 0; i < n; i++) {
tempSum += arr[i];
if (tempSum < 0)
tempSum = 0;
if (tempSum > maxSum)
maxSum = tempSum;
}
return maxSum;
}
時間復雜度:O(n)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
