classSolution: defminSubArrayLen(self, target: int, nums: List[int]) -> int: n = len(nums) ans = n + 1# 初始化为一个不可能达到的最大值 s = 0# 当前窗口内的元素之和 left = 0# 窗口左指针 for right, x inenumerate(nums): s += x # 右指针向右移动,累加当前数值 # 如果减去窗口最左侧的数后,和依然大于等于 target # 说明我们可以进一步收缩窗口以寻求更小的长度 while s - nums[left] >= target: s -= nums[left] left += 1 # 只要当前窗口和满足条件,就尝试更新最小长度 if s >= target: ans = min(ans, right - left + 1) return ans if ans <= n else0
复杂度分析
时间复杂度:$O(n)$,其中 $n$ 是数组的长度。虽然嵌套了 while 循环,但每个元素最多被访问两次(进入窗口一次,离开窗口一次)。
空间复杂度:$O(1)$,仅使用了几个辅助变量。
C++ 实现
在 C++ 中,我们可以使用类似的逻辑。注意处理和可能超过 int 范围的情况(虽然本题 target 和元素均为正整数且范围适中,但使用 long long 或 int 均可,取决于题目约束)。
classSolution { public: intminSubArrayLen(int target, vector<int>& nums){ int n = nums.size(); int left = 0; int sum = 0; int ans = n + 1; for (int right = 0; right < n; right++) { sum += nums[right]; // 标准滑动窗口收缩逻辑 while (sum >= target) { ans = min(ans, right - left + 1); sum -= nums[left++]; } } return ans > n ? 0 : ans; } };
classSolution: defminSubArrayLen(self, target: int, nums: List[int]) -> int: n = len(nums) ans = n + 1# 初始化为一个不可能达到的最大值 s = 0# 当前窗口内的元素之和 left = 0# 窗口左指针
for right, x inenumerate(nums): s += x # 右指针向右移动,累加当前数值
# 如果减去窗口最左侧的数后,和依然大于等于 target # 说明我们可以进一步收缩窗口以寻求更小的长度 while s - nums[left] >= target: s -= nums[left] left += 1
# 只要当前窗口和满足条件,就尝试更新最小长度 if s >= target: ans = min(ans, right - left + 1)