【问题标题】:Minimum Subarray which is larger than a Key大于键的最小子数组
【发布时间】:2013-06-13 23:20:03
【问题描述】:
我有一个整数数组(不一定是排序的),我想找到一个连续的子数组,它的值之和最小,但大于特定值K
例如:
输入:数组:{1,2,4,9,5},键值:10
输出:{4,9}
我知道在O(n ^ 2) 中执行此操作很容易,但我想在O(n) 执行此操作
我的想法:我在 O(n) 中无论如何都找不到这个,但我能想到的只是 O(n^2) 的时间复杂度。
【问题讨论】:
标签:
arrays
algorithm
computer-science
【解决方案1】:
假设它只能有正值。
那么就简单了。
解决方案是最小(最短)连续子数组之一,其总和为> K。
取两个索引,一个作为子数组的开始,一个作为结束(一个结束),以end = 0 和start = 0 开始。初始化sum = 0;和min = infinity
while(end < arrayLength) {
while(end < arrayLength && sum <= K) {
sum += array[end];
++end;
}
// Now you have a contiguous subarray with sum > K, or end is past the end of the array
while(sum - array[start] > K) {
sum -= array[start];
++start;
}
// Now, you have a _minimal_ contiguous subarray with sum > K (or end is past the end)
if (sum > K && sum < min) {
min = sum;
// store start and end if desired
}
// remove first element of the subarray, so that the next round begins with
// an array whose sum is <= K, for the end index to be increased
sum -= array[start];
++start;
}
由于仅增加两个索引,因此算法为O(n)。
【解决方案2】:
在 O(n) 时间和 O(1) 空间内工作的正数和负数(不完全确定负数)的 Java 实现。
public static int findSubSequenceWithMinimumSumGreaterThanGivenValue(int[] array, int n) {
if (null == array) {
return -1;
}
int minSum = 0;
int currentSum = 0;
boolean isSumFound = false;
int startIndex = 0;
for (int i = 0; i < array.length; i++) {
if (!isSumFound) {
currentSum += array[i];
if (currentSum >= n) {
while (currentSum - array[startIndex] >= n) {
currentSum -= array[startIndex];
startIndex++;
}
isSumFound = true;
minSum = currentSum;
}
} else {
currentSum += array[i];
int tempSum = currentSum;
if (tempSum >= n) {
while (tempSum - array[startIndex] >= n) {
tempSum -= array[startIndex];
startIndex++;
}
if (tempSum < currentSum) {
if (minSum > tempSum) {
minSum = tempSum;
}
currentSum = tempSum;
}
} else {
continue;
}
}
}
System.out.println("startIndex:" + startIndex);
return minSum;
}