算法导论-最大子数组问题-线性时间复杂度算法分析与实现
来源:互联网 发布:淘宝优惠券那个网站好 编辑:程序博客网 时间:2024/05/18 02:35
之前写了最大子数组问题的分治法,今天把这个问题的线性时间复杂度的算法写出来。
这个方法在算法导论最大子数组问题的课后思考题里面提出来了,只是说的不够详细。
思考题如下:使用如下思想为最大子数组问题设计一个非递归的,线性时间复杂度的算法。从数组左边界开始,由左至右处理,记录到目前为止已经处理过的最大子数组。若已知A[1...j]的最大子数组,基于如下性质将解扩展为A[1...j+1]的最大子数组:A[1...j+1]的最大子数组要么是A[1...j]的最大子数组,要么是某个子数组A[i...j+1](1<=i<=j+1)。在已知A[1...j]的最大子数组的情况下,可以在线性时间内找出形如A[i..j+1]的最大子数组
思考题里面已经把基本思想说的很清楚了,只是
“在已知A[1...j]的最大子数组的情况下,可以在线性时间内找出形如A[i..j+1]的最大子数组”
这句话里面描述的方法没有说出来.这里我先把我的结论说出来,接下来再证明。
结论:在已知A[1...j]的最大子数组的情况下(假设A[1..j]的最大子数组是A[k...l]),找出A[i..j+1](1<=i<=j+1)的最大子数组是如下三个子数组中的最大和
1.A[k...l]
2.A[k...j+1]
3.max{A[x...j+1] | x为k + 2 至 j + 1}
也就是说,如果新的最大子数组不是原来的最大子数组,那么新的最大子数组的终点必然是j+1.这个是显而易见的。
假设新的最大子数组不是原来的,那么起点是哪里呢?
1.起点不可能小于k。因为如果小于k,那么说明有A[x...j+1]>A[k...j+1](x<k),即存在A[x...k-1]>0,这显然是不可能的。
2.起点不可能大于k小于等于l。因为如果那样的话,说明有A[x...j+1]>A[k...j+1](k<x<=l),即A[k...x-1]<0,即最大子数组的起点到它中间某个点小于0,这是不可能的。
3.起点不可能位于j + 1,因为j+1必然小于0。
所以算法很容易就得出来了。
下面是这个问题的java实现。我没做多少测试,有错误的话请指正。
public class FindMaxSubIntArray {public static class Result {int max;int start;int end;}public static Result findMaxSubIntArray(int[] a) {if (a == null || a.length < 1)return null;Result res = new Result();res.max = a[0];res.start = 0;res.end = 0;for (int i = 1; i < a.length; i++) {int max1 = a[i];//max1求的是上述三个子数组中的第二个int max2 = a[i];//max2求的是上述有一个子数组的第三个int max2_start = i;for (int j = i - 1; j > res.end; j--) {//这里之所以求到res.end,没有避开res.end+1,是想要让max1加上res.end+1处的值max1 += a[j];if (max2 + a[j] > max2) {max2 += a[j];max2_start = j;}}max1 += res.max;if (max1 >= res.max && max1 >= max2) {res.max = max1;res.end = i;}if (max2 >= max1 && max2 >= res.max) {res.max = max2;res.start = max2_start;res.end = i;}}return res;}/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubint[] a = { 1,-2,4,-6,6,-2,-8 };Result res = findMaxSubIntArray(a);System.out.println(res.start + " " + res.end + " " + res.max);}}
0 0
- 算法导论-最大子数组问题-线性时间复杂度算法分析与实现
- 算法导论(最大子数组问题-线性时间复杂度算法分析与实现)
- 算法导论 4.1-5 最大子数组问题 线性时间算法 C++简单实现
- 算法导论-----最大子数组问题(线性解法)
- Java实现《算法导论》最大子数组问题
- 算法导论之最大子数组问题 C语言实现
- 算法导论4.1-3~4.1-5最大子数组暴力算法和递归算法的实现和线性时间算法实现
- 算法导论之最大子数组问题
- 【算法导论】最大子数组问题
- 算法导论--最大子数组问题
- 算法导论—最大子数组问题
- 【算法基础】算法导论-最大子数组问题
- 第四章 最大子数组问题(股票最大收益) C++实现 算法导论
- 递归式时间复杂度分析 《算法导论》
- 最大子列和问题的四种不同时间复杂度的算法实现
- 算法导论_最大子数组问题(分治策略)
- 最大子数组问题(动态规划)--【算法导论】
- 最大子数组问题(分治法)--【算法导论】
- WERTYU
- 使用GPIO模拟I2C总线进行通信
- HDU5289 Assignment
- linux ubuntu14.0.4中配置Apache tomcat的方法
- ffmpeg filter参数设置格式
- 算法导论-最大子数组问题-线性时间复杂度算法分析与实现
- Adaboost 算法的原理与推导
- 排列(c++ stl+哈希)
- Android 四大组件学习之Service五
- 如何提高并发度?读写锁,分拆锁、分离锁,ThreadLocal,copyOnWrite,工作队列 per thread, 工作窃取
- UVA 12563 Jin Ge Jin Que Hao
- 关于程序运行 IROM、IRAM解决方案
- 只使用处理IO的printDigit函数,编写一个过程以输出任意实数
- Spring框架下的管理员登录功能实现