给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其总和大于等于 target
的长度最小的 连续子数组
[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
解法一:双层循环暴力求解,但是对于大的测试用例超时。
从当前值开始逐渐向后搜索寻找大于target的子集,记录当前子集长度,找到所有子集后做个对比输出最小的那个子集。最后还要判断一下子集是否存在,不存在输出0.
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
m = [ ]
for i in range(n):
sum = 0
for j in range(i,n):
sum += nums[j]
if sum >= target:
m.append(j-i+1)
break
res = min(m) if m != [ ] else 0
return res
解法二:滑动窗口
滑动窗口通过一次全循环解决问题降低时间复杂度。与暴力求解不同的是它在大循环中先去寻找右端点并记录该数组长度,然后在该子数组满足和大于target时减去左端点的数值使和不满足target,程序继续寻找新的右端点并记录新的子数组长度,在程序结束后选择最小的子数组长度并输出。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
left = 0
right = 0
sums = 0
m = [ ]
while right < n:
sums += nums[right]
while sums >= target:
m.append(right-left +1)
sums -= nums[left]
left +=1
right+=1
res = min(m) if m != [ ] else 0
return res
子数组的长度也可以使用以下方法来比较,设置一个无穷大的mine,每一次满足条件时将当前的子数组长度与上一个满足条件的子数组长度做对比留下最小的值,有点类似于冒泡。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
left = 0
right = 0
sums = 0
n = len(nums)
mine = float('inf')
while right < n:
sums += nums[right]
while sums >= target:
mine = min(mine,right - left +1)
sums -= nums[left]
left += 1
right += 1
return mine if mine != float('inf') else 0