01-复杂度1 最大子列和问题
3月6日新一学期的《数据结构》MOOC开课了。我计划在这学期中,每周完成课后编程作业并在PTA平台提交获得满分后在此整理记录自己的解题思路、遇到的问题及需要注意的点等内容。以PTA平台中《中国大学MOOC-陈越、何钦铭-数据结构-2018春》习题集顺序更新。
第一讲的第一题,最大子列和问题,是课上例题。课中介绍了四种算法,在此我使用了第四种时间复杂度T(N) = O(N)的“在线处理”的方法:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define MAXSIZE 100000 4 5 int MaxSubsequenceSum(int Data[], int K) 6 { 7 int ThisSum = 0, MaxSum = 0; 8 int i; 9 for(i = 0; i < K; i++){ 10 ThisSum += Data[i]; 11 if(ThisSum > MaxSum) 12 MaxSum = ThisSum; 13 else if(ThisSum < 0) 14 ThisSum = 0; 15 } 16 return MaxSum; 17 } 18 19 int main(int argc, char const *argv[]) 20 { 21 int K; 22 int i; 23 int res; 24 int Data[MAXSIZE]; 25 scanf("%d", &K); 26 for(i = 0; i < K; i++) 27 scanf("%d", &Data[i]); 28 res = MaxSubsequenceSum(Data, K); 29 printf("%d\n", res); 30 return 0; 31 }
该方法的关键在于,及时对ThisSum的值进行判断:只要新加了一个元素后的ThisSum大于当前MaxSum,即进行更新;如果没有大于当前MaxSum,则准备进入下一循环继续累加新元素,但是这时得注意如果ThisSum已经小于0,则后面只会让ThisSum自己越来越小(加了负数),也没必要再跟MaxSum比较并更新,所以这种情况下需重新置ThisSum为0再进行下一轮累加循环。
举例一想更加直观。如输入6个数:1,2,5,-10,100,6。ThisSum循环进第四个数后值为-2,这时若不处理而再往后累加的话只会让100“损失”成98,所以应重置成0继续新的比较。