我在 javascript 中实现了 Kadane 的 Max Sub 数组问题,但似乎我最终总是在控制台中得到 0,即使存在更高的数字(我知道它做了它正在做的事情,因为 for loop from 0 - size
where size = subarray size
)。
那么如何正确实现算法呢?
它是否也适用于所有正整数数组?
我在 javascript 中实现了 Kadane 的 Max Sub 数组问题,但似乎我最终总是在控制台中得到 0,即使存在更高的数字(我知道它做了它正在做的事情,因为 for loop from 0 - size
where size = subarray size
)。
那么如何正确实现算法呢?
它是否也适用于所有正整数数组?
当您的数组长度为 6 时,您将 n=3 作为参数传递。我将您的算法更改为使用length
:
function SubSequence(a){
var now = 0,prev =0;
for(var i = 0;i < a.length;i++){
prev = Math.max(0,prev + a[i]);
now = Math.max(prev,now);
}
return now;
}
console.log(SubSequence([-1,-2,-3,4,6,7]));
它给出了 17。
它是否也适用于所有正整数数组?
是的,它将给出数组中所有元素的总和。
如果您想要长度为 3 的最大子序列,请使用
function SubSequence(a,n){
var now = 0;
for(var i = 0; i < n; i++) {
now += a[i];
}
var best = now;
for(var i = n;i < a.length;i++) {
now += a[i] - a[i-n];
best = Math.max(now,best);
}
return best;
}
console.log(SubSequence([-1,-2,-3,4,6,7,1,4],3));
最好是4+6+7,不允许4+6+7+1+4。
在计算机科学中,最大子数组问题是在具有最大和的一维数字数组(包含至少一个正数)中找到连续子数组的任务。
Kadane 算法是一种求解上述问题的方法。
Kadane 算法的简单想法是查找数组的所有正连续段(比如说 max_ending_here)。并跟踪所有正段之间的最大和连续段(比如说 max_so_far)。每次我们得到一个正和时,将其与 max_so_far 进行比较,如果它大于 max_so_far,则更新 max_so_far。
算法不适用于所有负数。如果所有数字都是负数,它只会返回 0。为了处理这个问题,我们可以在实际实施之前添加一个额外的阶段。如果所有数字都是负数,则该阶段将查看,如果它们是负数,它将返回其中的最大值(或绝对值的最小值)
您发布的是在数组中所有数字均为负数的情况下的实现。它不指实际算法,而只是一个额外的阶段。Kadane 的一维数组算法:
this is the general algorithm.
Initialize:
max_so_far = 0
max_ending_here = 0
Loop for each element of the array
(a) max_ending_here = max_ending_here + a[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far
希望这个解释对你有帮助。
然而,这个问题在这里很晚,以防万一它对任何人有帮助,我尝试解决这个问题,包括数组的所有元素都是负数的情况。
let allPositives = arr => arr.every(n => n > 0)
let allNegatives = arr => arr.every(n => n < 0)
let sum = arr => arr.reduce((curr_max, max_so_far) => curr_max + max_so_far, 0)
var getMaxArrNumber = function (arr) {
return Math.max.apply(null, arr);
}
var maxSequence = function(arr){
if(arr.length === 0 ) return 0;
if(allNegatives(arr)) return getMaxArrNumber(arr);
if(allPositives(arr)) return sum(arr);
var curr_max = 0, max_so_far = 0;
for(var i = 0; i < arr.length; i++){
curr_max = Math.max(0, curr_max + arr[i]);
max_so_far = Math.max(curr_max, max_so_far);
}
return max_so_far;
}