【问题标题】:Given an array and a sum, find the max length continous subarray less than the sum给定一个数组和一个总和,找到小于总和的最大长度连续子数组
【发布时间】:2016-11-16 22:35:32
【问题描述】:

我有一个数组 [1,2,3],总和为 4。所以所有连续子数组都是 [1],[1,2][2,3] 和 [1,2,3]。所以小于等于sum的最大长度子数组为[1,2],长度为2。

我已通过以下方式找到所有子数组并检查子数组的总和,如下所示。但是这种方法不适用于负数。 {1,2,1,1,3,-2,-3,7,9}; - 答:7

 private static void maximumSubArray(int[] a, int sum) {

    int start = 0;
    int end =0;
    int mylen =-1;
    int subarrSum =0;
    for(int i=0;i<a.length;i++){
        subarrSum += a[i];
        end++;
        while(subarrSum > sum){
            subarrSum-= a[start];
            start +=1;

        }

        mylen = Math.max(mylen, end-start);
    }
    System.out.println(mylen + "  -- My len");

}

【问题讨论】:

  • “有没有更好的方法??”是的。您可以按线性时间搜索。
  • "所以所有连续子数组都是"你忘了[2][3]

标签: java data-structures


【解决方案1】:

这是经典maximum contiguous subarray problem 的变体。你可以使用dynamic programming(记忆)来解决这个问题。试试这样的:

private static void maximumSubArray(int[] a, long sum, int maxLen) {
    long maximumSoFar = Long.MIN_VALUE;
    long maximumEndingHere = Long.MIN_VALUE;
    for (int i = 0; i < a.length; i++) {
        // if you're inside the array beyond maxLen, start dropping off the previous start element
        int prevStart = i >= maxLen ? a[i - maxLen] : 0;
        maximumEndingHere = Math.max(a[i], maximumEndingHere + a[i] - prevStart);
        if (maximumEndingHere > maximumSoFar && maximumEndingHere <= sum) {
            maximumSoFar = maximumEndingHere;
        } else if (a[i] > maximumSoFar && a[i] <= sum) {
            maximumSoFar = a[i];
        } else if (maximumEndingHere > sum) {
            maximumEndingHere -= prevStart;
        }
    }
    System.out.println(maximumSoFar);
}

如果我有更多时间,我会以更简洁的方式在 for 循环中编写逻辑,但这应该可以工作,并且可以在 O(n) 时间内工作。

【讨论】:

  • 我认为这种方法无法找到最大长度,因为在以下情况下它会失败。 {1,2,1,1,3,4,7,5,1,0,0,0,1,1,0,1};
  • @Vinny 我得试一试。
猜你喜欢
  • 2018-01-19
  • 1970-01-01
  • 2022-10-12
  • 2016-05-27
  • 2020-06-30
  • 2019-12-25
  • 2016-12-20
  • 2021-04-09
  • 2014-08-07
相关资源
最近更新 更多