/*
DJ.W 2012.12.27
代码功能:
输入: 一个整型数组
输出: 该数组能得到的最大连续元素和
如对输入 1 -2 -4 7 -6 9 最大连续元素和为10 (7 + (-6) + 9)
问题以及算法思想来自《编程珠玑(第二版)》P77
*/
#include <iostream>
using namespace std;
#define max(a, b) (a>b? a:b)
/*二分思想
思路,将数组从中间分为三个部分,左半部分,右半部分,和交界部分
数组中最大连续元素和必定是三者其一,也就是最大的那一个。
对于左右半部分,可以直接递归,中间部分就直接从中间开始向两边扩散。
复杂度为O(n) 整个算法复杂度为O(nlgn)
这个解法需要认真想想它是怎样保证得到的和一定是连续元素块的。
*/
int maxsum(int* p, int start, int end)
{
//终止条件 递归到长度为1的子数组,这个时候
//自然是该数是正就加上是负则舍去(返回0)
if(start == end)
{
if(p[start] > 0)
return p[start];
else
return 0;
}
//找到中点
int mid = (start+end)/2;
//从中点向左扩展 找到向左能得到的最大和
int sum_mid = 0;
int temp = 0;
for (int i= mid; i>=start; i--)
{
temp = temp+p[i];
if (temp > sum_mid)
sum_mid = temp;
}
temp = sum_mid;
//从中点向右扩展 找到向右扩展能得到的最大和
for (i = mid+1; i<=end; i++)
{
temp = temp+p[i];
if (temp > sum_mid)
sum_mid = temp;
}
//递归左右两半部分 得到三个部分中最大和
return max(max(maxsum(p, start, mid), maxsum(p, mid+1, end)), sum_mid);
}
/*扫描法
算法思想:
从左到右扫描数组A,当扫描到i时,设立两个变量sumCur和maxSofar
sumCur为当前扫描到的下标i之前得到的累加值。maxSofar是当前得到
过的最大元素和。如果sumCur = sum(A[0]...A[i])<=0
那么可以判定A[0...i]必定不会在最终得到的最大连续元素和的
序列中(这里假设我们力求得到的连续元素个数最少,因此加上了=)。
因此我们重设sumCur=0(相当于舍弃了A[0...i])
如果sumCur > 0 则继续扫描A[i+1] 此时如果A[i+1]>=0 那么
maxSofar = sumCur+A[i+1] 否则maxSofar不变。当扫描完数组后
maxSofar即为所求
*/
int maxsum_scan(int* arr, int size)
{
int sumCur = 0;
int maxSofar = 0;
for (int i=0; i<size; i++)
{
sumCur = max(sumCur+arr[i], 0);
maxSofar = max(maxSofar, sumCur);
}
return maxSofar;
}
int main()
{
int test[10] = {10, -9, 6, 33, -12, 5, 19, 8, 13, -2};
//int sum = maxsum(test, 0, 9);
int sum = maxsum_scan(test, 9);
cout<<"Test Sum = "<<sum<<endl;
return 0;
}
求数组最大连续元素之和
最新推荐文章于 2022-04-18 21:00:00 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)