1007. Maximum Subsequence Sum (25)


Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:


10 1 4

错误代码如下:

#include <stdio.h>int MaxSubseqSum4(int A[], int N, int* pstart, int* pend)
{int i = 0;int tempStart; //记录最大子段和位置int thisSum = 0, sum = 0;tempStart = 0;for (i = 0; i < N; i++) {thisSum += A[i];if (thisSum > sum) {sum = thisSum;*pstart = tempStart;*pend = i;} else if (thisSum < 0) {thisSum = 0;tempStart = i + 1;//每次及时更新,但不一定是最大和的首位置}}return sum;
}int main()
{int N = 0;int A[10001] = {0};int i;int flag = 0;int start, end, sum;scanf("%d", &N);for (i = 0; i < N; i++) {scanf("%d", A+i);if (*(A+i) >= 0) {flag = 1;}}if (flag == 0) { //如果序列的值全部<0printf("0 %d %d", A[0], A[N-1]);} else {sum = MaxSubseqSum4(A, N, &start, &end);printf("%d %d %d", sum, A[start], A[end]);}return 0;
}

错误提示:

异常退出???什么原因呢?

用 下面的例子可以明白

3

-1 0 0

这个测试数据代入程序,发现start,end两个变量没有被操作,而且也没有初始化,所以异常退出。

所以程序出错就是这个例子没有通过,所以必须考虑到这种情况,重新修改函数

MaxSubseqSum4

代码如下:

#include <stdio.h>int MaxSubseqSum4(int A[], int N, int* pstart, int* pend)
{int i = 0;int tempStart; //记录最大子段和位置int thisSum = 0, sum = -1;tempStart = 0;for (i = 0; i < N; i++) {thisSum += A[i];if (thisSum > sum) {sum = thisSum;*pstart = tempStart;*pend = i;} else if (thisSum < 0) {thisSum = 0;tempStart = i + 1;//每次及时更新,但不一定是最大和的首位置}}return (sum > 0 ? sum : 0);
}int main()
{int N = 0;int A[10001] = {0};int i;int flag = 0;int start, end, sum;scanf("%d", &N);for (i = 0; i < N; i++) {scanf("%d", A+i);if (*(A+i) >= 0) {flag = 1;}}if (flag == 0) { //如果序列的值全部<0printf("0 %d %d", A[0], A[N-1]);} else {sum = MaxSubseqSum4(A, N, &start, &end);printf("%d %d %d", sum, A[start], A[end]);}return 0;
}

测试结果:

上面的代码在时间上已经达到O(n),但是空间上是相当浪费的(A[10000]),而且如果数据再多了就出现了溢出的错误,针对这两点,修改代码如下:(参考了http://www.2cto.com/kf/201311/254392.html的代码)

下面是别人的优秀代码,此代码思路非常清晰简洁:

#include<iostream>  
using namespace std;  
int main()  
{  int N;  int *input;  int i;  int begin=0, end=0, sum=0;  //最终所求的子序列的起始位置,终止位置,以及子序列和。  int tempSum=0, tempBegin=0, tempEnd=0;  //目前正在考察的子序列的起始位置,终止位置,以及子序列的和。  cin>>N;     input = new int[N];   for(i=0; i<N; i++)  cin>>input[i];  end = N-1;    for(i=0; i<N; i++)  {  if(tempSum >= 0)  {  tempSum += input[i];  tempEnd = i;  }  else {  //如果tempSum<0,那么tempSum+input[i]<input[i]  //所以此时我们要开始考察新的子序列  tempSum = 0;   tempSum += input[i];  tempBegin = i;  tempEnd = i;  }  //if(tempSum > sum) 这样写不能AC,应改为如下:  if(tempSum > sum || (tempSum == 0 && end == N-1))  //{  sum = tempSum;  begin = tempBegin;  end = tempEnd;  }         }  cout<<sum<<" "<<input[begin]<<" "<<input[end]<<endl;  return 0;  
}  

下面对这段代码做数学分析:

从集合的角度,所有的子段和可以分为三类:>0, <0, =0,<0的直接就不用考虑了,>0的直接用tempSum > sum就可以处理这种情况,比较麻烦的是=0这种情况,根据题目要求,当tempSum == 0时必须更新begin,end的值,(题目中有:保证i,j都尽可能的小),但是只有第一次更新就行了,如果每次子段和为0都更新,否则就不能保证j尽可能的小了,于是有了end == N-1这个条件。如测试数据2 1 -1.

代码优化成在线方式,代码如下:

#include<iostream>  
using namespace std;  
int main()  
{  int N;  int a;  int i;  int begin=0, end=0, sum=0;  //最终所求的子序列的起始位置,终止位置,以及子序列和。  int tempSum=0, tempBegin = 0, tempEnd=0, allBegin = 0, allEnd = 0;  //目前正在考察的子序列的起始位置,终止位置,以及子序列的和。  int flag = 0;  int allNeg = 1;cin>>N;     for(i=0; i<N; i++)  {   cin >> a;if (i == 0) { //初始化tempBegin = a;allBegin = a;}if (i == N-1) { //初始化allEnd = a;}if (a >= 0) {  //判断是否全为负数allNeg = 0;}if(tempSum >= 0)  //记录当前tempSum值{  tempSum += a;  tempEnd = a;  }  else {  tempSum = 0;   tempSum += a;  tempBegin = a;  tempEnd = a;  }if(tempSum > sum || (tempSum == 0 && flag == 0))  {  sum = tempSum;  begin = tempBegin;  end = tempEnd;flag = 1;}         }  if (allNeg == 1)cout <<  "0" << " " << allBegin <<" "<< allEnd << endl;  elsecout << sum << " " << begin << " " << end << endl;return 0;  
}  

可对照上面的代码理解此代码,优化过的代码比较难读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于 ASP.NET MVC 中的视图生成

在 ASP.NET MVC 中&#xff0c;我们将前端的呈现划分为三个独立的部分来实现&#xff0c;Controller 用来控制用户的操作&#xff0c;View 用来控制呈现的内容&#xff0c;Model 用来表示处理的数据。 从控制器到视图 通常&#xff0c;在 Controller 中&#xff0c;我们定义多个…

2021-07-21

leetcode113 看了很多别人的题解&#xff0c;还是感觉没太懂&#xff0c;主要是因为dfs和bfs没彻底会用&#xff0c;还是得找专门的题练练。 得早睡早起呀&#xff0c;假期学习真就靠自律呀。 *** Definition for a binary tree node.* struct TreeNode {* int val;* …

实验项目 3-4:一元多项式的乘法与加法运算

代码如下&#xff1a; /*************************************************************************> File Name: AddPoly.c> Author: YueBo> Mail: yuebowhu163.com> Created Time: 2016年12月17日 星期六 13时00分35秒***************************************…

SQL自定义完整性

自定义完整性。&#xff08;事务&#xff09; 事务的四个特性&#xff1a; 原子性 : 事务中SQL语句是一个整体, 不可分离,要么都执行、要么都不执行 一致性 : 事务前后数据保持一致 隔离性 : 事务中不允许其他事务介入 永久性 : 事务执行之后对数据表的修改是永久的 Expectatio…

伪类和伪元素

选择第一个子元素&#xff1a;first-child li:first-child{text-decoration: underline;}li:last-child{color: red;}p:first-child{font-style: italic;} <p>xiaoren</p><ul><li>Insert Key</li><li>Turn Key<strong>clockwise<…

T-SQL存储过程

存储过程。即T-SQL里的方法。类似封装的思想。 基本语法如下&#xff1a; create proc 方法名 name 默认值可不写&#xff0c;传入的参数 数据类型 , p变量名 数据类型 output (返回值) asSql代码 go--调用上面方法 declare variable 和p一样的类型 exec 方法名 传值 , var…

Extjs4开发中的一些问题

1. 子frame刷新的问题 一般在jsp里面&#xff0c;要实现界面跳转&#xff0c;有很多方法&#xff0c;最典型的就是window.location.href"href",但是在嵌套有iframe框架的页面布局&#xff0c;使用上述语句&#xff0c;只会使iframe本身实现跳转&#xff0c;如果遇到…

TSQL索引与视图

创建视图 简化sql 代码&#xff0c;还有&#xff0c;给予权限&#xff08;只能查指定的列&#xff09; create view 视图名 as sql代码&#xff0c;不要有同名列&#xff08;只能一句sql代码&#xff09; go select * from 视图名 &#xff08;最好不要用视图做更改操作&#…

jacob 实现Office Word文件格式转换

关于jacob用法&#xff0c;百度一下就会发现几乎都是复制2004年一个代码&#xff0c;那段代码实现的是从一个目录读取所有doc文件&#xff0c;然后把它转html格式。 为了便习学习和使用&#xff0c;我把代码看懂后精简了一下&#xff0c;得出不少新结论&#xff0c;拿出来和大家…

2021-07-22

leetcode547 第一次做这种题&#xff0c;有点生&#xff0c;借鉴 class Solution { public:void dfs(vector<vector<int>>& isConnected,vector<int>&isvisited,int i){for(int j0;j!isConnected.size();j){if(isConnected[i][j]1&&isvisit…

树的同构

输入样例1&#xff08;对应图1&#xff09;&#xff1a;8A 1 2B 3 4C 5 -D - -E 6 -G 7 -F - -H - -8G - 4B 7 6F - -A 5 1H - -C 0 -D - -E 2 -输出样例1:Yes输入样例2&#xff08;对应图2&#xff09;&#xff1a;8B 5 7F - -A 0 3C 6 -H - -D - -G 4 -E 1 -8D 6 -B 5 -E - -…

.Net 中的封装知识点

c # 中的封装 1&#xff0c;类与对象 生活中现有对象&#xff0c;然后人们先对其归类。 而程序中&#xff0c;先有类&#xff0c;再有对象。有了这些类&#xff0c;才能生成实际的对象&#xff0c;即类的实例化。&#xff08;类名new 一个对象&#xff09; 对象是从类里那东西的…

[家里蹲大学数学杂志]第236期钟玉泉复变函数论前六章第二组习题参考解答

第一章 复数与复变函数 1将复数 $$\bex \frac{(\cos5\varphii\sin 5\varphi)^2}{(\cos3\varphi-i\sin 3\varphi)^3} \eex$$ 化为指数形式. 解答: 由 Euler 公式, $$\bex \mbox{原式}\frac{(e^{i5\varphi})^2}{(e^{-i3\varphi})^3} e^{i[10\varphi-(-9\varphi)]}e^{19\varphi…

思想

思想是自由的&#xff0c;鞭策和束缚下的思想不会深刻&#xff0c;所以不要强迫自己去思考和学习&#xff0c;除非你在那里找到了乐趣&#xff1b; 思想是懒惰的&#xff0c;稍不留神就可能走入邪道&#xff0c;或者呼呼的在那里享受睡觉&#xff1b; 所以最好的办法是&#…

.Net 中的继承知识点

.Net 中的面向对象 继承 继承思想的应用是为了解决封装遗留下来的代码冗余的问题。但这是简单的理解。 在一个系统开发中会有重复的成员&#xff0c;所以找到这些共有的成员&#xff0c;把它们装进一个类中&#xff0c;即父类。 语法 A:B A类继承了B,B 是父类。 A类可访问B类中…

Java单例模式简单实现

代码 public class Singleton {private static Singleton singleton;//创建一个单例对象public static Singleton getSingleton(){if(singleton null){//判断对象是否为空singleton new Singleton();}return singleton;} } public class Test {public static void main(Strin…

2021-07-23

leetcode46 第一次写回溯的题&#xff0c;思想还是dfs&#xff0c;就是多了一步恢复原状态&#xff0c;之前好像也写过。每天做的有点少&#xff0c;得加油了 class Solution { public:vector<vector<int>> permute(vector<int>& nums) {vector<vec…