【问题标题】:Does Kadane's Max Sub Array algorithm work on all positive integer array?Kadane 的 Max Sub Array 算法是否适用于所有正整数数组?
【发布时间】:2012-06-07 05:22:25
【问题描述】:

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

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

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

JsBin

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

【问题讨论】:

    标签: javascript algorithm arrays kadanes-algorithm


    【解决方案1】:

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

    【讨论】:

    • @sdcwc 我如何知道总和为 17 的子数组的大小?它是否总是等于数组的长度。我认为您可以指定算法将扫描的子数组大小并告诉最大和数组
    • Deeptechtons:算法告诉最大和而不考虑它的长度。你想知道在这个例子中结果的长度是 3,还是你想找到一个长度为 3 且总和最大的中缀?
    【解决方案2】:

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

    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
    

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

    【讨论】:

      【解决方案3】:

      这个问题很晚,但是,为了以防万一它对任何人有帮助,我尝试解决这个问题,包括数组的所有元素都是负数的情况。

      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-12-14
        • 1970-01-01
        • 1970-01-01
        • 2021-12-04
        • 2020-08-25
        • 1970-01-01
        • 1970-01-01
        • 2012-04-11
        • 1970-01-01
        相关资源
        最近更新 更多