209 长度最小的子数组
题目 209长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
思路
注意审题:连续最小的子数组,这里我们想到的是滑动窗口的方法来做。
-
所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
-
在暴力解法中,是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环 完成了一个不断搜索区间的过程。
-
那么滑动窗口如何用一个for循环来完成这个操作呢。
-
首先要思考 如果用一个for循环,那么应该表示滑动窗口的起始位置,还是终止位置。
-
如果只用一个for循环来表示滑动窗口的起始位置,那么如何遍历剩下的终止位置?
-
此时难免再次陷入暴力解法的怪圈。
-
所以 只用一个for循环,那么这个循环的索引,一定是表示滑动窗口的终止位置
代码
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
start = 0 # 起始位置
res = len(nums)
sum = 0
for end in range(len(nums)): # 循环终止位置
sum += nums[end]
while sum >= target:
subl = end - start + 1
res = min(res, subl)
sum -= nums[start]
start += 1
if start == 0: # 判断列表之和小于target,start没有动,说明一直没有后移,sum没有大于target。还有种笨方法就是开头for循环对列表求和
return 0
else:
return res