Welcome to Subscribe On Youtube
209. Minimum Size Subarray Sum
Description
Given an array of positive integers nums
and a positive integer target
, return the minimal length of a subarray whose sum is greater than or equal to target
. If there is no such subarray, return 0
instead.
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] <= 104
Follow up: If you have figured out the O(n)
solution, try coding another solution of which the time complexity is O(n log(n))
.
Solutions
Solution 1: Prefix Sum + Binary Search
First, we preprocess the prefix sum array $s$ of the array $nums$, where $s[i]$ represents the sum of the first $i$ elements of the array $nums$. Since all elements in the array $nums$ are positive integers, the array $s$ is also monotonically increasing. Also, we initialize the answer $ans = n + 1$, where $n$ is the length of the array $nums$.
Next, we traverse the prefix sum array $s$. For each element $s[i]$, we can find the smallest index $j$ that satisfies $s[j] \geq s[i] + target$ by binary search. If $j \leq n$, it means that there exists a subarray that satisfies the condition, and we can update the answer, i.e., $ans = min(ans, j - i)$.
Finally, if $ans \leq n$, it means that there exists a subarray that satisfies the condition, return $ans$, otherwise return $0$.
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
Solution 2: Two Pointers
We can use two pointers $j$ and $i$ to maintain a window, where the sum of all elements in the window is less than $target$. Initially, $j = 0$, and the answer $ans = n + 1$, where $n$ is the length of the array $nums$.
Next, the pointer $i$ starts to move to the right from $0$, moving one step each time. We add the element corresponding to the pointer $i$ to the window and update the sum of the elements in the window. If the sum of the elements in the window is greater than or equal to $target$, it means that the current subarray satisfies the condition, and we can update the answer, i.e., $ans = \min(ans, i - j + 1)$. Then we continuously remove the element $nums[j]$ from the window until the sum of the elements in the window is less than $target$, and then repeat the above process.
Finally, if $ans \leq n$, it means that there exists a subarray that satisfies the condition, return $ans$, otherwise return $0$.
The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array $nums$.
-
class Solution { public int minSubArrayLen(int target, int[] nums) { int n = nums.length; long s = 0; int ans = n + 1; for (int i = 0, j = 0; i < n; ++i) { s += nums[i]; while (j < n && s >= target) { ans = Math.min(ans, i - j + 1); s -= nums[j++]; } } return ans <= n ? ans : 0; } }
-
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int n = nums.size(); long long s = 0; int ans = n + 1; for (int i = 0, j = 0; i < n; ++i) { s += nums[i]; while (j < n && s >= target) { ans = min(ans, i - j + 1); s -= nums[j++]; } } return ans == n + 1 ? 0 : ans; } };
-
class Solution: def minSubArrayLen(self, target: int, nums: List[int]) -> int: n = len(nums) ans = n + 1 s = j = 0 for i, x in enumerate(nums): s += x while j < n and s >= target: ans = min(ans, i - j + 1) s -= nums[j] j += 1 return ans if ans <= n else 0
-
func minSubArrayLen(target int, nums []int) int { n := len(nums) s := 0 ans := n + 1 for i, j := 0, 0; i < n; i++ { s += nums[i] for s >= target { ans = min(ans, i-j+1) s -= nums[j] j++ } } if ans == n+1 { return 0 } return ans }
-
function minSubArrayLen(target: number, nums: number[]): number { const n = nums.length; let s = 0; let ans = n + 1; for (let i = 0, j = 0; i < n; ++i) { s += nums[i]; while (s >= target) { ans = Math.min(ans, i - j + 1); s -= nums[j++]; } } return ans === n + 1 ? 0 : ans; }
-
public class Solution { public int MinSubArrayLen(int target, int[] nums) { int n = nums.Length; long s = 0; int ans = n + 1; for (int i = 0, j = 0; i < n; ++i) { s += nums[i]; while (s >= target) { ans = Math.Min(ans, i - j + 1); s -= nums[j++]; } } return ans == n + 1 ? 0 : ans; } }
-
impl Solution { pub fn min_sub_array_len(target: i32, nums: Vec<i32>) -> i32 { let n = nums.len(); let mut res = n + 1; let mut sum = 0; let mut i = 0; for j in 0..n { sum += nums[j]; while sum >= target { res = res.min(j - i + 1); sum -= nums[i]; i += 1; } } if res == n + 1 { return 0; } res as i32 } }