求和最大的子数组
来源:互联网 发布:深圳西乡淘宝培训 编辑:程序博客网 时间:2024/04/28 08:15
问题描述:
一个数组中包含正数和负数,其中位置相邻的若干元素称为子数组,求总和最大的子数组,举例{1, -2, 3, 10, -4, 7, 2, -5},最大子数组是{3, 10, -4, 7, 2},要求时间复杂度为O(n)
问题分析:
首先考虑临界情况,如果数组中全是负数,则直接返回数组中的最大负数即可,
现在考虑一般情况,即数组中至少存在一个正数,因为时间复杂度要求为 O(n) ,即要求只能对数组进行一次遍历,我们假定从左往右遍历,
我们先简化考虑,将原数组中所有相邻的正数相加,所有相邻的负数也相加,例如:
{-1, -2 ,5 ,-2, 10,16, -2 , -4, -9, 1, 2},简化后就变成{-3, 5 , -2 , 26, -15, 3}
可以看到,简化后的数组正负数是间隔着排列的,现在分析简化后的数组,如下是以从左往右遍历的第一个和第二个正数为端点的子数组的几种可能情况:
1) 5, -2, 26 ---负数小于两端的正数
2) 5, -12, 26 --负数大于左边的正数,小于右边的正数
3) 26, -12, 5 --负数小于左边的正数,大于右边的正数
4) 12, -26, 5 --负数大于两端的正数
对于上述1),当遍历到第二个正数时,总和最大的子数组是可能包括这个子数组{5, -2, 26}的,并且总和是 5 + (-2)+ 26 = 29,
对于上述2),当遍历到第二个正数时,总和最大的子数组肯定不可能包括第一个正数了,所以可以放心的把第一个正数抛弃,所以子数组为{26},总和是26,
对于上述3),当遍历到第二个正数时,总和最大的子数组肯定包括第一个正数,第二个正数可能包括,因为咱们不知道第二个正数后面还有没有更大的正数,所以
这里既要保留当前总和最大的子数组{26}、最大值26,又要保留子数组{26, -12, 5}、总和 26 + (-12)+ 5 = 19,
对于上述4),当遍历到第二个正数时,总和最大的子数组要么就是子数组{12},要么就包括第二个正数{5},理由同上,因为有可能第三个正数很大,
从上分析可以得出,至少设置4个临时变量:当前总和最大的子数组int[] maxArr及其总和 int max,有可能总和最大的子数组int[] currMaxArr及其总和 int currMax,
这样遍历到第三个正数时,将currMax作为左边的端点,第三个正数作为右边的端点,作上述同样的判断,并将计算得出的最大值和max比较,如果比max大,就替换max和maxArr的值。后续就是不断的重复此过程,一直到数组的最后一个元素。
代码如下:
public static List<Integer> test(int[] n){int max = 0;//子数组和的最大值List<Integer> maxArr = new ArrayList<Integer>();//最大值对应的子数组int currMax = 0;//当前计算的最大值List<Integer> currMaxArr = new ArrayList<Integer>();//当前最大值对应的子数组maxArr.add(n[0]);for(int i=0; i<n.length; i++){if(currMax < 0){currMax = n[i];currMaxArr.removeAll(currMaxArr);currMaxArr.add(n[i]);}else{currMax += n[i];currMaxArr.add(n[i]);}if(max < currMax){max = currMax;maxArr.removeAll(maxArr);maxArr.addAll(currMaxArr);}}return maxArr;}
- 求和最大的子数组
- 二维数组最大子矩阵的求和
- 分治法求和最大的子数组
- 求和最大的子矩阵
- 遇到的比较有意思的问题(1)去掉重复数字(2)提取数组的子数组,求和最大的子数组、最大的子数组和
- 有一个数组,由正整数、负整数、零组成,求和最大的连续子数组
- 一个数组,有正有负,不改变顺序的情况下,求和最大的最长子序列
- 求和最大的连续子串问题
- 求和最大的连续子串
- 最大子数组的求和方法一(非动态规划)
- 最大子序列求和
- 最大子序列求和
- 最大子序列求和
- 最大子序列求和
- 最大子矩阵求和
- 最大子段求和
- 最大子序列求和
- Uva 507 - Jill Rides Again(最大子数组求和问题)
- 站长而不可以点击自己网站中的广告?
- 利用DB2进行分页
- <c:forEach>
- 有“接”有“纳” 户籍制度改革瞄准破除城乡壁垒
- Android项目实战--手机卫士34--流量管理
- 求和最大的子数组
- 预处理命令 # 和 ##
- VC屏幕截图,保存为Bmp文件
- 网线回路的制作方法
- STL Bitsets ---应用
- java注解解析
- v8 hack ---给js添加新的关键字
- 内存设备描述表
- 求1!+2!+3!+。。。。。。+20!