一、实践题目

  7-2 最大子段和

二、问题描述

  要求编写一个时间复杂度为O(n)的算法,去求解给定n个整数(包含负数)组成的序列a[1],a[2],a[3],…,a[n]中的子段和的最大值,规定当所给的整数均为负数时,定义子段和为0。

三、算法描述

   定义一个辅助数组note[n],note[i]记录序列a[1],a[2],a[3],…,a[i]中以a[i]结尾的子段和的最大值,note[i]初始化为a[i]。从a[2]开始,一直到a[n],更新note[i]的值,若note[i - 1]大于0,note[i]的值变为note[i - 1] + note[i]。循环结束后,由1至n, 找出note[i]的最大值,即为所求问题的解。

  具体代码如下:

 

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main() {
 5     int n;
 6     cin >> n;
 7     int a[n];
 8     int note[n];
 9     for (int i = 0; i < n; i++) {
10         cin >> a[i];
11     note[i] = a[i];
12     }
13     for (int i = 1; i < n; i++)
14     note[i] = note[i - 1] > 0 ? note[i - 1] + note[i] : note[i];
15     int max = note[0];
16     for (int i = 1; i < n; i++)
17     if (note[i] > max)
18         max = note[i];
19     if (max < 0)
20     max = 0;
21     cout << max << endl;
22     return 0;
23 }

四、算法时间及空间复杂度分析

算法时间复杂度:

  该算法更新note[i]时,包含一个1~n的for循环(内部为判断条件,更新note[i],为常数级操作),查找最大值时,也包含一个1~n的for循环,故该算法时间复杂度为O(n)。

算法空间复杂度:

  该算法使用了一个一维数组note[n],note[i]记录序列a[1],a[2],a[3],…,a[i]中以a[i]结尾的子段和的最大值。故该算法空间复杂度为O(n)。若是不需要读取输入序列,则可进一步优化该算法的空间复杂度,直接在a[n]的基础上进行操作,该算法空间复杂度将变为O(1)。

五、心得体会

  本次为我和搭档的第二次上机实验,该题采用的是动态规划,算是动态规划中较为简单的一道。在编写本题时,我们先是各自思考思路,双方都想清楚之后交流想法,巧合的是我们的思路完全一致。

posted on 2018-11-05 12:05  薪王的骨灰  阅读(134)  评论(0编辑  收藏  举报