求数组最大连续元素之和

来源:互联网 发布:淘宝能货到付款吗 编辑:程序博客网 时间:2024/05/07 02:59
/*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];elsereturn 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和maxSofarsumCur为当前扫描到的下标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;}

原创粉丝点击