连续子数组求和
2018-01-08 15:39
190 查看
LINTCODE 402 - 连续子数组求和
今天,求LINTCODE娘给我题目的时候,给了我这么一个充满回忆的题目,这个题目可谓是倾倒众生,一遍又一遍地出现,居家旅行面试必备,我也就着记忆里的印象,将当初看到这个最佳解法时的惊艳写出来和各位读者分享一下。================================================================================================================
已知:
给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大。输出答案时,请分别返回第一个数字和最后一个数字的下标。(如果两个相同的答案,请返回其中任意一个)
示例:
给定 [-3, 1, 3, -3, 4], 返回[1,4].
================================================================================================================
思路如下:
记录一个最大值,暂时不考虑数组全是负数的情况,默认为0
-3 为 负数,舍弃,进入下一个数字
1 为正数,默认当前最大值为1, 开始和结束下标为1,1
1 + 3 为4,正数,且比最大值1要大,最大值改为4,开始和结束下标为1,2
4 + -3 为1,正数,但是值比最大值小了,不处理
1 + 4 为5, 正数,且比最大值4要大,最大值改为5,开始和结束下标位1,4
遍历完成,当前最大值为5,开始和结束下标位1,4
这个一个复杂度为O(n)的算法。
================================================================================================================
这个算法的正确性,我们来观察一下:[... start ...
end ...],最佳答案的特征
start和end代表的数字应该是正数,且如果start和end不是边界,start左边和end右边的数字应该是负数
这里有点意会的意味了,其实我们的算法就是遍历了从每个可以作为开始下标的数字开始的最大值,然后从所有的最大值中选最大的,找出得出这个值时的开始和结束下标。
================================================================================================================
public class Solution { public List<Integer> continuousSubarraySum(int[] A) { if (onlyMinusDigit(A)) { int index = getMaxIndex(A); List<Integer> ret = new ArrayList<Integer>(); ret.add(index); ret.add(index); return ret; } int maxvalue = 0; int temp = 0; int start = 0; int[] index = new int[2]; for (int i = 0; i < A.length; i++) { temp += A[i]; if (temp < 0) { temp = 0; start = i + 1; } if (temp > maxvalue) { maxvalue = temp; index[0] = start; index[1] = i; } } List<Integer> ret = new ArrayList<Integer>(); ret.add(index[0]); ret.add(index[1]); return ret; } private static int getMaxIndex(int[] a) { int maxvalue = a[0]; int index = 0; for (int i = 1; i < a.length; i++) { if (a[i] > maxvalue) { index = i; } } return index; } private static boolean onlyMinusDigit(int[] a) { for (int num : a) { if (num >= 0) { return false; } } return true; } }
谢谢您的阅读,希望您意会到了这个算法的精髓,这样想必不需要看我的代码,就能在源代码基础上找到如何得出start和end下表的方法,^_^
相关文章推荐
- 连续子数组求和
- LintCode: 连续子数组求和
- lintcode,连续子数组求和
- 给定任意数组获取任意连续的项求和的最大值,并输出新的数组
- lintcode刷题--连续子数组求和
- 数组求和的艺术-一个数组最大连续字数组之和
- 连续子数组求和
- 连续子数组求和
- lintcode-402-连续子数组求和
- mooc题 素数的判断,素数求和,字符串数组
- 对于一个数组{1,2,3}它的子数组有{1,2},{1,3}{2,3},{1,2,3},元素之间可以不是连续的,对于数组{5,9,1,7,2,6,3,8,10,4},升序子序列有多少个?
- 时间效率:连续子数组的最大和
- 求数组中的最大连续和
- 从零开始学_JavaScript_系列(七)——jquery(复选框及互斥、div块、修改css、标签数组、ajax连续加载)
- Crystal自定义函数(转换为大写,返回数组,求和)
- jquery数组求和
- 连续子数组最大和问题编程实现
- Oracle 10g中用FORALL处理非连续数组
- 最大连续字串求和
- js 数组对象的求和、过滤、多重排序的方法封装