LeetCode热题(JS版) - 209. 长度最小的子数组

53 阅读1分钟

题目描述

给定一个含有n个正整数的数组和一个正整数s,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0。

示例:

输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。

解题思路

我们可以使用双指针法滑动窗口来解决这道题。定义两个指针 leftright 分别表示子数组的左右端点,初始时两个指针都指向位置 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) 的快速解决方案,是非常实用的一种算法思路。