Kadane的Max Sub Array算法是否适用于所有正整数数组?

时间:2012-06-07 05:22:26

标签: javascript algorithm arrays kadanes-algorithm

我在javascript中实现了Kadane的Max Sub数组问题但似乎我最终总是在控制台中得到0,即使存在更高的数字(我知道它做了它正在做的事情因为for从0 - size循环size = subarray size)。

  • 那么我该如何正确实现算法?

  • 它是否也适用于所有正整数数组?

JsBin

http://jsbin.com/ajivan/edit#javascript,live

3 个答案:

答案 0 :(得分:10)

当你的数组长度为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。

答案 1 :(得分:1)

在计算机科学中,最大的子阵列问题是在一维数字(包含至少一个正数)中找到具有最大总和的连续子阵列的任务。

Kadane算法是一种找到上述问题解决方案的方法。

Kadane算法的简单概念是查找数组的所有正连续段(比如max_ending_here)。并跟踪所有正片段中的最大总和连续片段(比如说max_so_far)。每次我们得到一个正数并与max_so_far进行比较,如果它大于max_so_far则更新max_so_far。

算法不适用于所有负数。如果所有数字都是负数,它只返回0。为了处理这个问题,我们可以在实际实施之前添加额外的阶该阶段将查看所有数字是否为负数,如果它们将返回它们的最大值(或绝对值最小)

你发布的是在数组中所有数字都是负数的情况下的实现。它不是指实际的算法,而只是一个额外的阶段。 Kadane的1 D阵列算法:

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
希望这个解释对你有所帮助。

答案 2 :(得分:0)

在这个问题上非常晚了,但是,为了防止任何人,我对问题的尝试,包括阵列的所有元素都是否定的情况。

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;
}