编程珠玑中给出了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章算法设计技术