1、题目

leetcode_209长度最小的子数组_滑动窗口

2、分析

    我之前分析的时候分析错了,其实是对题目理解不清,我以为的连续子数组,是指的不仅仅在空间上连续,而且是在内容上连续,比如1,2,3,4,或者是4,3,2,1。

    这种理解就导致了做题很复杂。

    官方给的有几种解决办法,一种是暴力搜索,一种是二分查找,一种是滑动窗口。

    推荐第二种和第三种,第三种更好。

    leetcode_209长度最小的子数组_C++_02

 

    leetcode_209长度最小的子数组_双指针_03

 

 

3、代码

    方法二

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int n = nums.size();
        if (n == 0) {
            return 0;
        }
        int ans = INT_MAX;
        vector<int> sums(n + 1, 0); 
        // 为了方便计算,令 size = n + 1 
        // sums[0] = 0 意味着前 0 个元素的前缀和为 0
        // sums[1] = A[0] 前 1 个元素的前缀和为 A[0]
        // 以此类推
        for (int i = 1; i <= n; i++) {
            sums[i] = sums[i - 1] + nums[i - 1];
        }
        for (int i = 1; i <= n; i++) {
            int target = s + sums[i - 1];
            auto bound = lower_bound(sums.begin(), sums.end(), target);
            if (bound != sums.end()) {
                ans = min(ans, static_cast<int>((bound - sums.begin()) - (i - 1)));
            }
        }
        return ans == INT_MAX ? 0 : ans;
    }
};

     leetcode_209长度最小的子数组_数组_04

 

     方法三

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int n = nums.size();
        if (n == 0) {
            return 0;
        }
        int ans = INT_MAX;
        int start = 0, end = 0;
        int sum = 0;
        while (end < n) {
            sum += nums[end];
            while (sum >= s) {
                ans = min(ans, end - start + 1);
                sum -= nums[start];
                start++;
            }
            end++;
        }
        return ans == INT_MAX ? 0 : ans;
    }
};

     leetcode_209长度最小的子数组_双指针_05

 

纵一苇之所如,临万顷之茫然。