给定一个含有 n 个正整数的数组和一个正整数 target 。
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
if not nums:
return 0
n = len(nums)
ans = n + 1
for i in range(n):
total = 0
for j in range(i, n):
total += nums[j]
if total >= s:
ans = min(ans, j - i + 1)
break
return 0 if ans == n + 1 else ans
方法一的时间复杂度是 O(n2),因为在确定每个子数组的开始下标后,找到长度最小的子数组需要 O(n) 的时间。如果使用二分查找,则可以将时间优化到 O(logn),总的变为O(nlogn)
-因为这道题保证了数组中每个元素都为正,所以前缀和一定是递增的,这一点保证了二分的正确性。如果题目没有说明数组中每个元素都为正,这里就不能使用二分来查找这个位置了。
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
if not nums:
return 0
n = len(nums)
ans = n + 1
sums = [0]
for i in range(n):
sums.append(sums[-1] + nums[i])
for i in range(1, n + 1):
target = s + sums[i - 1]
bound = bisect.bisect_left(sums, target)
if bound != len(sums):
ans = min(ans, bound - (i - 1))
return 0 if ans == n + 1 else ans
在方法一和方法二中,都是每次确定子数组的开始下标,然后得到长度最小的子数组,因此时间复杂度较高。为了降低时间复杂度,可以使用滑动窗口的方法。
初始状态下,start 和 end 都指向下标 0,sum 的值为 0。
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
if not nums:
return 0
n = len(nums)
ans = n + 1
start, end = 0, 0
total = 0
while end < n:
total += nums[end]
while total >= s:
ans = min(ans, end - start + 1)
total -= nums[start]
start += 1
end += 1
return 0 if ans == n + 1 else ans
class Solution:
def hs(self, nums, sum, left, right, target):
if sum < target:
return 0;
if left<=right:
if nums[left]>nums[right]:
sum -= nums[right]
if sum >= target:
return self.hs(nums, sum, left, right-1, target)
elif nums[left]<nums[right]:
sum -= nums[left]
if sum >= target:
return self.hs(nums, sum, left+1, right, target)
else:
tmp = sum - nums[left]
if tmp >= target:
a = self.hs(nums, tmp, left+1, right, target)
b = self.hs(nums, tmp, left, right-1, target)
return min(a,b)
return right-left+1
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
sum = 0
for i in range(n):
sum += nums[i]
ans = self.hs(nums, sum, 0, n-1, target)
return ans
力扣(LeetCode)是领扣网络旗下专注于程序员技术成长和企业技术人才服务的品牌。源自美国硅谷,力扣为全球程序员提供了专业的IT技术职业化提升平台,有效帮助程序员实现快速进步和长期成长。此外,力扣(LeetCode)致力于解决程序员技术评估、培训、职业匹配的痛点,逐步引领互联网技术求职和招聘迈向专业化。
【1】https://leetcode.cn/problems/minimum-size-subarray-sum/description/