题目描述
给定一个含有n个正整数的数组和一个正整数s,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
解题思路
我们可以使用双指针法滑动窗口来解决这道题。定义两个指针 left 和 right 分别表示子数组的左右端点,初始时两个指针都指向位置 0,然后我们不断地增加 right 指针来扩大滑动窗口,直到窗口内的数字和大于等于了 s,此时我们记录当前子数组的长度并与当前最小值比较,然后将 left 指针右移,缩小子数组范围,再次计算子数组的和,如此循环直到 right 指针到达数组尽头。
代码实现
function minSubArrayLen(s: number, nums: number[]): number {
let left = 0;
let right = 0;
let sum = 0;
let minLen = Infinity;
while (right < nums.length) {
sum += nums[right];
right++;
while (sum >= s) {
minLen = Math.min(minLen, right - left);
sum -= nums[left];
left++;
}
}
return minLen === Infinity ? 0 : minLen;
}
时间/空间复杂度
本算法的时间复杂度为 O(n),其中 n 是数组的长度。在算法的执行过程中,左右指针各移动了 n 次,因此总时间复杂度为 O(n)。
该算法只使用了常数级别的额外存储空间,因此其空间复杂度为 O(1)。
总结
这道题使用双指针法可以达到时间复杂度为 O(n) 的快速解决方案,是非常实用的一种算法思路。