4

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

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

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

杰宾

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

4

3 回答 3

11

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

于 2012-06-07T05:36:48.940 回答
1

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

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

希望这个解释对你有帮助。

于 2013-10-16T10:17:23.137 回答
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;
}
于 2017-07-29T20:22:52.560 回答