给定一个数组和一个和,找到最大长度连续子阵列小于总和

时间:2016-11-16 22:35:33

标签: java data-structures

我有一个数组[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");

}

1 个答案:

答案 0 :(得分:0)

这是经典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)时间内工作。