Table of contents
Given problem
Given an array of positive integers nums
and a positive integer target
, return the minimal length of a contiguous subarray [numsl, numsl+1, ..., numsr-1, numsr]
of which the sum is greater than or equal to target
. If there is no such subarray, return 0 instead.
For example:
-
Example 1:
Input: target = 7, nums = [2,3,1,2,4,3] Output: 2 Explanation: The subarray [4,3] has the minimal length under the problem constraint.
-
Example 2:
Input: target = 4, nums = [1,4,4] Output: 1
-
Example 3:
Input: target = 11, nums = [1,1,1,1,1,1,1,1] Output: 0
Constraints:
1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
Using brute-force solution
In this case, we need to iterate all contiguous subarrays in the nums
array. So below is some steps to iterate all of them.
-
Use two loops.
- The outer loop will be used to mark the beginning of the current subarray.
-
The inner loop will be used to iterate all elements from that index of the outer loop.
- Calculate sum
- Then, compare sum with
target
’s value.
So, we have brute-force solution for this problem.
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int minSize = Integer.MAX_VALUE;
int outerIdx = -1;
int innerIdx = -1;
for (outerIdx = 0; outerIdx < nums.length; ++outerIdx) {
int sum = 0;
for (innerIdx = outerIdx; innerIdx < nums.length; ++innerIdx) {
sum += nums[innerIdx];
if (sum >= target) {
minSize = Math.min(minSize, innerIdx - outerIdx + 1);
break;
}
}
}
if (minSize == Integer.MAX_VALUE) {
return 0;
}
return minSize;
}
}
The complexity of this solution:
- Time complexity: O(n^2)
- Space complexity: O(1)
Using Binary Search algorithm with Prefix-sum
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int size = nums.length;
if (size == 0) {
return 0;
}
int[] sums = new int[size + 1];
Arrays.fill(sums, 0);
for (int i = 1; i <= size; ++i) {
sums[i] = sums[i - 1] + nums[i - 1];
}
System.out.println("Sums: " + Arrays.toString(sums));
int minSubArraySize = Integer.MAX_VALUE;
for (int i = 1; i <= size; ++i) {
int value = target + sums[i - 1];
int idx = lowerBound(sums, value);
if (idx != -1) {
minSubArraySize = Math.min(minSubArraySize, idx - i + 1);
}
}
return (minSubArraySize != Integer.MAX_VALUE) ? minSubArraySize : 0;
}
private static int lowerBound(int[] prefixSum, int target) {
int low = -1;
int high = prefixSum.length;
while (low + 1 != high) {
int mid = low + (high - low) / 2;
if (prefixSum[mid] < target) {
low = mid;
} else {
high = mid;
}
}
if (high < prefixSum.length) {
return high;
}
return -1;
}
}
The complexity of this solution:
- Time complexity: O(nlogn)
- Space complexity: O(n)
Wrapping up
Refer: