题目描述
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的
子数组
[numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路
- 我们需要在一个全为正整数的数组中寻找满足和 ≥ target 的最短连续子数组。
- 所有数均为正整数,子数组的和随窗口的扩大而单调增加,这使得滑动窗口方法非常适合。窗口由两个指针 left(窗口左边界)和 right(窗口右边界)确定。
- 整体思路是:
当找到满足条件的子数组,记录窗口长度(right - left + 1)并尝试收缩窗口(即移动 left 指针)以寻找更短的子数组。
重复上述过程,直至遍历完整个数组。若未找到满足条件的窗口,则返回 0。
代码
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
left = 0 # 初始化窗口左边界
current_sum = 0 # 当前窗口内数值总和为0
min_len = float('inf') # 初始化最小长度为正无穷
# 遍历数组
for right in range(0, n):
current_sum += nums[right] # 加入右侧新元素
# 当当前窗口和 >= target 时,尝试不断缩小窗口找更短的满足条件的子数组
while current_sum >= target:
min_len = min(min_len, right-left+1)
current_sum -= nums[left]
left += 1
return 0 if min_len == float('inf') else min_len
拓展总结
- 滑动窗口算法核心思想
“滑动窗口”的双阶段过程:先扩展窗口(右指针移动)以满足条件,再不断收缩窗口(左指针移动)以寻找最小窗口。
不断收缩:条件满足后,窗口可能还可以进一步缩小以得到更优解,需要用循环不断尝试收缩窗口,而不是仅执行一次。 - 滑动窗口增量更新
扩大窗口:加入右侧新元素
收缩窗口:移除左侧元素,并将左边界右移 - 数组下标和区间长度(元素个数)的基本概念
“闭区间”的概念,即如果两个边界都是包含的,元素数量就是 (右边界索引 - 左边界索引 + 1)。
558

被折叠的 条评论
为什么被折叠?



