209长度最小的子数组

发布时间 2023-04-20 20:48:56作者: chuxin_jian

力扣刷题 209 长度最小的子数组--day2

题目分析

??? 在写代码前, 还是要好好分析, 最好在纸上把题目的过程模拟以下

思路清晰,代码才会不写的很乱,

像这道题,一开始很难想到用滑动窗口的, 只有在纸上模拟了子数组的变化过程才写的出来!

今天时间有点紧, 题解就不分析过多了,

我的解法

//自己的写法, 本质上是滑动窗口
int minSubArrayLen(int target, vector<int>& nums) {
    int size = nums.size();
    int left = 0, right = 0;
    int ll = 0,rr = 0;
    int sum = 0, minLength = 100005;
    while(right < size){
        while(right < size && sum < target){
            sum += nums[right];
            right++;
        }
        if(sum < target){
            break;
        }
        while(sum >= target){
            sum -= nums[left];
            left++;
        }
        if(right - left + 1 < minLength){
            minLength = right - left + 1;
            ll = left - 1;
            rr = right - 1;
        }
    }
    if(minLength == 100005) return 0;
    else {
        for(int i = ll; i <= rr; i++){
            cout<< nums[i]<<" ";
        }
        return minLength;
    }
}

carl 哥的精炼版本

省去了不必要的循环

// 代码精炼版
int minSubArrayLen(int s, vector<int>& nums) {
    int result = INT32_MAX;
    int sum = 0; // 滑动窗口数值之和
    int i = 0; // 滑动窗口起始位置
    int subLength = 0; // 滑动窗口的长度
    for (int j = 0; j < nums.size(); j++) {
        sum += nums[j];
        // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
        while (sum >= s) {
            subLength = (j - i + 1); // 取子序列的长度
            result = result < subLength ? result : subLength;
            sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
        }
    }
    // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
    return result == INT32_MAX ? 0 : result;
}