给定一个数组和一个总和,找到小于总和的最大长度连续子数组
Posted
技术标签:
【中文标题】给定一个数组和一个总和,找到小于总和的最大长度连续子数组【英文标题】: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]
。
【参考方案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 我得试一试。以上是关于给定一个数组和一个总和,找到小于总和的最大长度连续子数组的主要内容,如果未能解决你的问题,请参考以下文章