動機

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