这道题用滑动窗口的方法,Python3代码如下:
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
#滑动窗口
left = 0
min_len = float("inf")
sum = 0
for right in range(len(nums)):
sum+=nums[right]
while(sum>=target):
min_len = min(min_len,right - left + 1)
sum-=nums[left]
left+=1
if min_len == float("inf"):
return 0
return min_len
博主本人一开始以为滑动窗口是一个固定大小的窗口从左到右依次挪动,还在疑惑这跟暴力解法有何区别,实际上,我们可以把滑动窗口的变化理解为毛毛虫爬行:伸长——缩小——再伸长
窗口的头部先固定,尾部从左往右逐个元素伸展,直到收集的sum符合条件。
然后保持尾部不动,从左往右逐个元素地收缩头部,每个被抛弃的元素都要从刚刚收集的sum中减去,并更新最小窗口长度(最小毛毛虫的长度),直到不满足while循环的条件。
下一步毛毛虫尾部继续往右逐个元素伸展,直到又一次满足sum的条件,然后又可以进入循环收缩头部了。
如此往复,直到毛毛虫尾部到达数组终点。
看上去很简单,但是滑动窗口为什么会有用呢?
看个例子:
数组:1,2,1,4,3
需要的Target=7
如果是暴力解法,我们需要遍历以下情况:
1 1,2 1,2,1 1,2,1,4 1,2,1,4,3
2 2,1 2,1,4 2,1,4,3
1 1,4 1,4,3
4, 4,3
3
但滑动窗口却只需要遍历以下情况:
1 1,2 1,2,1 1,2,1,4
2,1,4 2,1,4,3
1,4,3
4,3
对比可以发现少了这些情况:
1 1,2 1,2,1 1,2,1,4 1,2,1,4,3
2 2,1 2,1,4 2,1,4,3
1 1,4 1,4,3
4, 4,3
3
对此我的理解是,当窗口变为1,2,1,4时就可以知道2 2,1肯定不满足条件了,毕竟这个窗口挪到1,2,1,4了才刚刚满足条件,那单独的2和2,1肯定更不满足了,所以我们可以直接跳过。滑动窗口根据上一步的结果聪明地直接pass掉了更不满足条件的情况,提高了效率,这就是滑动窗口有效的原因。