第二章上机实验报告

7-1 最大子列和问题 (20分)

给定K个整数组成的序列{ N1​​, N2​​, ..., NK​​ },“连续子列”被定义为{ Ni​​, Ni+1​​, ..., Nj​​ },其中 1。“最大子列和”则被定义为所有连续子列元素的和中最大者。

例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

对最大子列和的分析: 我对于题目的理解是这样子的:给定一个数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),然后返回其最大和

 1 int maxWidth(int left, int right){
 2     //递归算法--每个递归内部包含三个求值操作
 3     //1、中位数左边(mid)的最大序列和
 4     //2、中位数右边(mid+1)的最大序列和
 5     //3、相对中位数来说跨了左右的最大序列和
 6     
 7     //每个递归结束条件的判断
 8     if(left==right){
 9         return a[left];
10     }
11     int mid = (left+right)/2;
12     int lch = maxWidth(left, mid);//计算左边的最大序列和
13     int rch = maxWidth(mid+1, right);//计算右边的序列和
14     //计算跨左右的最大子序列和
15     int lnum, rnum;
16     int ln = 0;//辅助判断
17     lnum=a[mid];
18     //计算从 mid 开始向左累加的最大序列和
19     for(int i=mid;i>=left;i--){
20         ln+=a[i];
21         if(ln>lnum)  lnum=ln;
22     }
23     rnum=a[mid+1];
24     ln=0;
25     //计算从 mid+1 开始向右累加的最大序列和
26     for(int i=mid+1;i<=right;i++){
27         ln+=a[i];
28         if(ln>
29         rnum)  rnum=ln;
30     }
31     return maxNum(rnum+lnum, lch, rch);
32 }
View Code

上面是我的核心代码,利用了递归分治的思想,每次递归进行三大步的操作,第一步在当前中心点向左搜索找出最大子序列和,第二步在当前中心点向右搜索找出最大子序列和,第三步在中心点下标分别向右和向左遍历找出最大子序列和,上述三者的最大值作为本层递归的返回值给上一层递归进行调用。

时间复杂度O(n*lg n)   这里用主定理去求解 T(n) = 2*T(n/2) + O(n)

每次将问题分解为两个子问题,每个子问题的长度为原问题的一半, O(n)包含了问题分解和子问题解合并的代价,从代码上来看,分解的过程包含了一些 O(1)的操作,然后有两个循环体,一个是从头到中间,另外一个是从中间到尾部, 所以加起来时间复杂度为 O(n), O(n) = n的 logb a次方 , log b a = 1, 因为 a=b时要成一个 lgn 所以总的时间复杂度为 O(n*lg n) 

心得:有些地方要看清楚题目的描述,比如说全为负数的时候返回的是0 而不是最大的负数,之前想当然的认为是返回最大负数。

原文地址:https://www.cnblogs.com/jintao1990/p/13791773.html