[英]Maximum Sum Subarray O(n) not Kadane's
我正在阅读Cormen的“算法简介”。
对于最大和子数组问题的线性算法,我想出了自己的解决方案。 在实施之前没有检查现有的(Kadena的)。
现在,我正在使用不同的测试场景对其进行测试,并且始终具有比Kadena更好的结果。 我不相信这种运气,但是找不到我错过的东西。 您能否看一下这是否是可行的解决方案?
public void findMaxSubarray(Number[] numbers) {
int maxSum = Integer.MIN_VALUE;
int left = 0;
int right = numbers.length - 1;
int i = 0;
int j = i + 1;
int sum = numbers[i].intValue();
while (i < numbers.length) {
if (maxSum < sum) {
maxSum = sum;
left = i;
right = j - 1;
}
if (j >= numbers.length)
return;
sum = sum + numbers[j].intValue();
if (sum <= 0) {
// ignoring "first" negative numbers. shift i to first non-negative
while (numbers[j].intValue() <= 0) {
if (maxSum < numbers[j].intValue()) {
maxSum = numbers[j].intValue();
left = j;
right = j;
}
if (++j >= numbers.length)
return;
}
i = ++j;
sum = 0;
}
j++;
}
System.out.println(String.format("Max subarray is %d, [%d; %d]", maxSum, left, right));
}
更新代码的想法是仅跟踪一个子数组,并在其尾数加到尾号上,当数字太低时,该和变为负数-在尾后设置数组的开头。 另外,开头的否定项将被忽略。 子数组的头部只是向前移动。 每次总和看起来都是最大-maxSum和限制会更新。
shift i() --to first non negative number
from j = i+1 up to N.length
sum + N[j]
if sum <= 0
i = j+1
if N[i] < 0
shift i()
sum = 0
我认为您的算法基本上是合理的,但是我可以看到两个错误:
1 -2 10 3
,它将跳过10并输出3。我认为您可以通过更改i = ++j;
来解决此问题i = ++j;
到i = j;
。 j
超过结尾,您return
在2个不同的地方return
,这将导致根本不产生任何输出! (例如,如果一长串负数出现在列表的末尾,则会发生这种情况。) 我也不希望它比Kadane的更快或更慢。 将两个数字相加是一种快速的操作,就像将一个变量复制到另一个变量一样快,这就是您在移动子数组起始位置时所执行的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.