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下表的方法,^_^