
Given an array of positive integers nums and a positive integer target, return the minimal length of a contiguous subarray of which the sum is greater than or equal to target. If there is no such subarray, return 0 instead.
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.
Input: target = 4, nums = [1,4,4]
Output: 1
Input: target = 11, nums = [1,1,1,1,1,1,1,1]
Output: 0
1 <= target <= 1091 <= nums.length <= 1051 <= nums[i] <= 105If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log(n)).
max(nums) and divde it to the left and right part that includes max(nums). Then find the minimum length of subarray in both part and return the smaller one.max() value will be included in the minimum size subarray.# target=10
nums=[5,5,1,1,7,1,1]The right subarray should be [5,5] but through above approach, it will return [1,1,7].
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
min_end=0
min_len=len(nums)
w_sum=nums[0]
if sum(nums)<target: return 0
if nums[-1]>=target: return 1
for i in range(len(nums)-1):
if i>0:
w_sum-=nums[i-1]
if i>min_end:
min_end=i
# find the min subarray
while min_end<len(nums):
if w_sum<target:
min_end+=1
if min_end==len(nums):break
w_sum+=nums[min_end]
if w_sum>=target:
min_len=min(min_len,min_end-i+1)
break
# print("-------------")
return min_len
Time Complexity: O(N)
The worst case is when the minumum subarry is nums array itself.
Space Complexity: O(1)
class Solution:
def minSubArrayLen(self, s, nums):
total = left = 0
result = len(nums) + 1
for right, n in enumerate(nums):
total += n
while total >= s:
result = min(result, right - left + 1)
total -= nums[left]
left += 1
return result if result <= len(nums) else 0
left and inner loop is for `rightright and inner loop is for leftmin_lenclass Solution:
def minSubArrayLen(self, target, nums):
result = len(nums) + 1
for idx, n in enumerate(nums[1:], 1):
nums[idx] = nums[idx - 1] + n
left = 0
for right, n in enumerate(nums):
if n >= target:
left = self.find_left(left, right, nums, target, n)
result = min(result, right - left + 1)
return result if result <= len(nums) else 0
def find_left(self, left, right, nums, target, n):
while left < right:
mid = (left + right) // 2
if n - nums[mid] >= target:
left = mid + 1
else:
right = mid
return left
References