#209
Medium
滑动窗口
Minimum Size Subarray Sum
求和至少为 target 的最短子数组长度。
求和至少为 target 的最短连续子数组长度。因为数组元素都是正数,所以一旦窗口和达到 target,就应该立刻尝试收缩。
ArraySliding Window
题目定位
因为数组元素为正,一旦当前和达到 target,想继续变短就只能收缩左边界,这是典型正数滑窗。
关键观察
正数保证了窗口和随指针移动具有单调性,这也是为什么这里滑窗比前缀和方案更自然。
目标复杂度
O(n) / O(1)
这题的解法思路怎么拆
1
维护当前窗口的区间和。
2
右指针不断扩张,直到窗口和达到或超过 target。
3
只要窗口仍然合法,就更新答案并持续收缩左边界。
4
正数条件正是这套逻辑成立的原因。
拿一个例子顺一遍
1
例如 target = 7, nums = [2, 3, 1, 2, 4, 3]。
2
扩到 [2, 3, 1, 2] 时,sum = 8,因此答案先变成 4。
3
继续收缩左边界得到 [3, 1, 2],sum = 6,窗口失效。
4
后面当 [4, 3] 出现时,答案进一步缩短为 2。
参考实现
Pythondef minSubArrayLen(target: int, nums: list[int]) -> int:
left = 0
window_sum = 0
best = float("inf")
for right, value in enumerate(nums):
window_sum += value
while window_sum >= target:
best = min(best, right - left + 1)
window_sum -= nums[left]
left += 1
return 0 if best == float("inf") else best
常见坑点
warning
把滑窗误用到包含负数的数组上。
warning
窗口仍然合法时,没有持续收缩到不能再收缩。
高频追问
为什么一旦有负数,这套滑窗逻辑就不成立了?
如果改成前缀和 + 二分,思路会怎样?
继续刷相关题
先把 滑动窗口 这个模式刷成体系,再去做更难变体。