您的位置:首页 > 其它

求子数组之和最大值(包括循环)

2012-02-08 15:07 239 查看
编程珠玑中给出了n*logn的解法,很有参考价值。O(n)的扫描方法,用到了前面分析的若干策略:

1) 从某个位置开始,到i位置结束的sum的计算方法是max_ending_here + array[i]

2)以往的最大值是max_sofar,要和到当前结束点的最大值进行比较取其大者

3)如果max_ending_here + array[i]的值小于array[i]的值,说明max_ending_here是负值,应该从新计数

4)如果max_sofar的值==max_ending_here的值,说明获得了一个最大值,应该更新开始和结束的位置信息

--------------

对于循环数组,需要计算好一下几个方面的内容:

1)要计算好数组的index

2)如果是第二轮了,有重新开始计数了,那么就可以退出了,因为后面的情况已经计算过了(或许也不对,因为从这个位置开始,再经过循环数组可能产生新的数组,和第一轮可能不一样?)

3)如果数组整体和大于0,那么可能会循环不停下来,因为不断循环,最大值不断加大,这是需要有一个终止条件,比如,循环2次终止

程序代码如下:

#include <stdio.h>
template<typename T>
T Max(const T& left, const T& right) {
if (left < right) {
return right;
} else {
return left;
}
}
int MaxSum(int array[], int begin, int end, int* max_start, int* max_end) {
*max_start = 0;
int max_sofar = 0x80000001;
printf("max_sofar = %d\n", max_sofar);
int max_ending_here = 0;
int start = 0;
for (int i = begin; i <= end; ++i) {
max_ending_here = Max(max_ending_here + array[i], array[i]);
if (max_ending_here == array[i]) {
start = i;
}
max_sofar = Max(max_sofar, max_ending_here);
if (max_sofar == max_ending_here) {
*max_start = start;
*max_end = i;
}
}
return max_sofar;
}

int CircleArrayMaxSum(int array[], int begin, int end, int* max_start, int* max_end) {
int i = 0;
bool next_round = false;
int array_size = end - begin + 1;
int max_sofar = 0x80000000;
int max_ending_here = 0;
int start = 0;
while (true) {
if (i > array_size) {
next_round = true;
}
max_ending_here = Max(max_ending_here + array[i % array_size], array[i % array_size]);
if (max_ending_here == array[i % array_size]) {
start = i % array_size;
if (next_round) {
break;
}
}
max_sofar = Max(max_sofar, max_ending_here);
if (max_sofar == max_ending_here) {
*max_start = start;
*max_end = i % array_size;
}
i++;
if (i  >= 2 * array_size) {
break;
}
}
return max_sofar;
}

int main(int argc, char** argv) {
int array[] = {-2, 5, 3, -6, 4, -8, 6};
//int array[] = {-9, -2, -3, -5, -3};
//  int array[] = {0, -1, 3, 5, -1, 2};
int max_start = -1;
int max_end = -1;
int array_length = sizeof(array) / sizeof(int);
int max_sum = MaxSum(array, 0, array_length - 1, &max_start, &max_end);
printf("no circle: max_sum = %d, start= %d, end = %d\n", max_sum, max_start, max_end);
max_sum = CircleArrayMaxSum(array, 0, array_length - 1, &max_start, &max_end);
printf("no circle: max_sum = %d, start= %d, end = %d\n", max_sum, max_start, max_end);
}


参考文献:

编程之美P183 2.14

编程珠玑 第8章算法设计技术
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: