题目:
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
双指针解法:
function minSubArrayLen(target, nums = []) {
let result = Number.MAX_SAFE_INTEGER // 返回最终的sum最小区间的长度 初始化成最大值 方便比较
let subLen = 0 // 记录滑动窗口子序列长度
let sum = 0
let i = 0 // 滑动窗口的起始位置
// 外层for循环更新终止位置j
for (let j = 0; j < nums.length; j++) {
sum += nums[j] // 做累加
// 修改i动态调节滑动窗口的位置
while (sum >= target) {
subLen = j - i + 1 // 更新当前最小区间元素的长度 因为i和j是索引从0开始 所以要+1
result = subLen < result ? subLen : result // 取结果比较取较小的一方
sum -= nums[i] // 减去i偏移量的值
i++ // 减去上一个数后起始位置后移一位
}
}
return result === Number.MAX_SAFE_INTEGER ? 0 : result // 没有就返回0
}
console.log(minSubArrayLen(7, [2, 3, 1, 2, 4, 3])) // 2
时间复杂度不是O(n2),虽然是for套while双从循环,但是滑动窗口移动时元素一进一出实际访问次数是2次,所以是2n,也就是O(n)