I have an array of integers (not necessarily sorted), and I want to find a contiguous subarray which sum of its values are minimum, but larger than a specific value K
e.g. :
input : array : {1,2,4,9,5} , Key value : 10
output : {4,9}
I know it's easy to do this in O(n ^ 2) but I want to do this in O(n)
My idea : I couldn't find anyway to this in O(n) but all I could think was of O(n^2) time complexity.
Let's assume that it can only have positive values.
Then it's easy.
The solution is one of the minimal (shortest) contiguous subarrays whose sum is > K.
Take two indices, one for the start of the subarray, and one for the end (one past the end), start with end = 0 and start = 0. Initialise sum = 0; and 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;
}
Since both indices only are incremented, the algorithm is O(n).
Java implementation for positive and negative(not completely sure about the negative numbers) numbers which works in O(n) time with O(1) space.
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;
}
来源:https://stackoverflow.com/questions/17157097/minimum-subarray-which-is-larger-than-a-key