最大子列和问题
2016-03-20 11:43
387 查看
一. 给定N个整数的序列{A1, A2,...,An},求函数
![](https://img-blog.csdn.net/20160320110700086)
的最大值
1. 算法一:
![](https://img-blog.csdn.net/20160320112121186)
上面这个算法是以下面方式累加的:
1) 当i = 0 时候,
![](https://img-blog.csdn.net/20160320112531441)
![](https://img-blog.csdn.net/20160320112538567)
![](https://img-blog.csdn.net/20160320112545328)
![](https://img-blog.csdn.net/20160320112551453)
.....
![](https://img-blog.csdn.net/20160320112557161)
当i = 1时候,
![](https://img-blog.csdn.net/20160320113138158)
![](https://img-blog.csdn.net/20160320113143886)
....
![](https://img-blog.csdn.net/20160320113150424)
2. 算法二:
对于相同的i,不同的j,只要在j - 1次循环的基础上累加1项即可。
![](https://img-blog.csdn.net/20160320113439316)
时间复杂度:
![](https://img-blog.csdn.net/20160320114250241)
3. 第三种算法:分而治之
把数组一份为二,采用递归的方法去解决左右两边的问题,
递归的解决左边的问题,会得到左边的最大子列和,
递归的解决右边的问题,会得到右边的最大子列和,
跨越边界的最大子列和,把这三个结果找到,我最后的结果一定是这三个最大的。
开始是分,最后的合成是治。
![](https://img-blog.csdn.net/20160320115124088)
![](https://img-blog.csdn.net/20160320115132319)
![](https://img-blog.csdn.net/20160320115144538)
![](https://img-blog.csdn.net/20160320115144538)
![](https://img-blog.csdn.net/20160320115150632)
如何求跨越子列和:
![](https://img-blog.csdn.net/20160320165407652)
时间复杂度:
![](https://img-blog.csdn.net/20160320170454087)
4. 算法四:在线处理
![](https://img-blog.csdn.net/20160320172755721)
![](https://img-blog.csdn.net/20160320172806565)
![](https://img-blog.csdn.net/20160320172811228)
![](https://img-blog.csdn.net/20160320172816612)
![](https://img-blog.csdn.net/20160320172821315)
![](https://img-blog.csdn.net/20160320172826009)
![](https://img-blog.csdn.net/20160320172830487)
![](https://img-blog.csdn.net/20160320172835228)
![](https://img-blog.csdn.net/20160320172839721)
![](https://img-blog.csdn.net/20160320172846893)
时间复杂度:
![](https://img-blog.csdn.net/20160320173053082)
5. 运行时间比较:
的最大值
1. 算法一:
<span style="font-size:14px;">int MaxSubseqSum1(int A[], int N) { int ThisSum, MaxSum = 0; int i, j, k; for(i = 0; i < N; i++)/* i是子列左端位置 */ { for(j = i; j < N; j++)/* j是子列右端位置 */ { ThisSum = 0;/* ThisSum是从A[i]到A[j]的子列和 */ for(k = i; k <= j; k++) { ThisSum += A[k]; } if(ThisSum > MaxSum)/*如果刚得到的这个子列和更大*/ { MaxSum = ThisSum;/* 则更新结果 */ } }/* j循环结束 */ }/* i循环结束 */ return MaxSum; }</span>时间复杂度:
上面这个算法是以下面方式累加的:
1) 当i = 0 时候,
.....
当i = 1时候,
....
2. 算法二:
对于相同的i,不同的j,只要在j - 1次循环的基础上累加1项即可。
<span style="font-size:14px;">int MaxSubseqSum2(int A[], int N) { int ThisSum, MaxSum = 0; int i, j; for(i = 0; i < N; i++)/* i是子列左端位置 */ { ThisSum = 0;/* ThisSum是从A[i]到A[j]的子列和 */ for(j = i; j < N; j++)/* j是子列右端位置 */ { ThisSum += A[k]; /*对于相同的i,不同的j,只要在j-1次循环的基础上累加1项即可*/ if(ThisSum > MaxSum)/*如果刚得到的这个子列和更大*/ { MaxSum = ThisSum;/* 则更新结果 */ } }/* j循环结束 */ }/* i循环结束 */ return MaxSum; }</span>
时间复杂度:
3. 第三种算法:分而治之
把数组一份为二,采用递归的方法去解决左右两边的问题,
递归的解决左边的问题,会得到左边的最大子列和,
递归的解决右边的问题,会得到右边的最大子列和,
跨越边界的最大子列和,把这三个结果找到,我最后的结果一定是这三个最大的。
开始是分,最后的合成是治。
如何求跨越子列和:
从中间开始,往左边扫描,然后往右边扫描。没个原始都会被扫描一次。 从中间线开始往左逐个累加,然后找到从中间左边第一个开始累加的最大值, 然后从中间往右逐个累加,然后找到从间接线右边第一个开始累加的最大值。 然后把左右两边给合并起来,得出的结果就是跨越子列和的最大值。 |
时间复杂度:
4. 算法四:在线处理
最大值就是:7 |
int MaxSubseqSum4(int A[], int N) { int ThisSum, MaxSum; int i; ThisSum = MaxSum = 0; for(i = 0; i < N; i++) { This+=A[i];/*向右累加*/ if(ThisSum > MaxSum) { MaxSum = ThisSum;/*发现更大和则更新当前结果*/ } else if(ThisSum < 0)/* 如果当前子列和为负 */ { ThisSum = 0;/* 则不可能使后面的部分和增大,抛弃之 */ } } return MaxSum; }
时间复杂度:
“在线”的意思是指每输入一个数据就进行即时处理,在任何一个地方中止输入,算法都能正确给出当前的解。 |
相关文章推荐
- PAT Maximum Subsequence Sum (25)
- HDU 1003 && HDU 1081(最大子列和,最大子矩阵和).
- 【第一周】最大子列和问题整理
- 算法笔记-1-最大子列和-Maximum Subsequence Sum
- 求最大子列和
- pat 最大子列和问题
- 最大子列和问题(JAVA)
- 最大子列和的四种算法总结
- [Data Structure] Maximum Subsequence Sum
- 1007. Maximum Subsequence Sum (25)
- 1007. Maximum Subsequence Sum (25)
- 求整数序列的最大子列和
- Kafka学习之三 Kafka线上环境集群部署及客户端应用
- 巧用Windows自带portproxy远程直接连接linux虚拟机
- vbs : 将WPS表格另存为文本文件
- PB数据窗口导出excel,修改第一行英文标题为中文标题,计算合计值
- android开发系列之socket编程
- 解决:Unable to execute dex: Multiple dex files define Landroid/annotation/AnimRes
- 剑指offer:和为S的连续正数序列
- SASS组件开发