【LeetCode-滑动窗口】长度最小的子数组

题目描述

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

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

题目链接: https://leetcode-cn.com/problems/minimum-size-subarray-sum/

思路

使用滑动窗口来做。使用两个指针 left 和 right 来表示滑动窗口,窗口的大小为 right-left+1。left 和 right 均初始化为 0。使用变量 curSum 记录窗口内元素的和。首先扩大窗口大小(增大 right),记录窗口内元素的和 curSum,如果 curSum>=s,则通过增大 left 来缩小窗口。算法如下:

  • 如果 right<nums.size(),循环:
    • 扩大 right,并将 nums[right] 加到 curSum;
    • 如果 curSum>=s,循环:
      • 将当前最小长度与窗口大小 right-left+1 作比较并根据两者大小更新答案;
      • 从 curSum 中减去 nums[left],left++,缩小窗口;

代码如下:

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        if(nums.empty()) return 0;

        int left = 0, right = 0;
        int curSum = 0;
        int minLen = INT_MAX;
        while(right < nums.size()){
            curSum += nums[right];
            
            while(curSum >= s){
                minLen = min(right-left+1, minLen);
                curSum -= nums[left];
                left++;
            }
            right++;
        }

        if(minLen == INT_MAX) return 0; // 注意可能没有答案
        else return minLen;
    }
};

需要特别注意最后的返回值,因为可能没有答案。

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
posted @ 2020-05-23 22:08  Flix  阅读(163)  评论(0编辑  收藏  举报