動機
與560不同他可以用sliding window
- prefix sum + binary search
- prefix sum in fly + sliding window
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.
Example 1:
Input: target = 7, nums = [2,3,1,2,4,3]Output: 2Explanation: 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
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))
.Sol
內容物只有正數,可以用sliding window
class Solution:
def minSubArrayLen(self, k: int, nums: List[int]) -> int:
a = 0
cnt = nums[0]
ret = float('inf')
for b,n in enumerate(nums[1:]+[0],1):
while a<b and cnt >= k:
ret = min(ret, b-a)
cnt -= nums[a]
a += 1
cnt += n
return ret if ret != float('inf') else 0
或是,利用prefix sum去找lower bound,這樣符合題目的要求
class Solution:
def minSubArrayLen(self, k: int, nums: List[int]) -> int:
sums, cnt, ret = [[0], 0, float('inf')]
for i in range(len(nums)):
cnt += nums[i]
sums.append(cnt)
for (i,left) in enumerate(sums):
j = bisect_left(sums,k+left)
if j < len(sums):
ret = min(ret, bisect_left(sums,k+left)-i)
return ret if ret != float('inf') else 0