柚子快报激活码778899分享:逐步优化求解最大子序列和

http://www.51969.com/

求解最大子序列和

tag: 数据结构与算法

最大子序列和问题:

给定序列A1, A2,... AN, 求最大的子序列和。

例如 :

  对于序列4, -3, 5, -2, -1, 2, 6, -2, 最大序列和为11(4 -3 + 5 - 2 - 1 + 2 + 6)

算法一:

利用两个循环,第一个循环把序列遍历一遍,第二个循环则从Ai累加到AN,每加一次判断一下是否大于之前的最大子序列和:

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(n2)

算法二:

首先把序列从中间一分为二, 则最大子序列和的存在有三种情况:

全在左边的子序列

全在右边的子序列

处在中间

对于第一和第二种情况,只需要递归调用求解函数,对于第三种情况则要分别求出从中间出发,向左边和向右边各自的最大子序列和。

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)

柚子快报激活码778899分享:逐步优化求解最大子序列和

http://www.51969.com/

查看原文