【代码随想录刷题记录】LeetCode209长度最小的子数组

题目地址

1. 思路

1.1 基本思路及代码实现

按照卡尔老师的思路,这个题目涉及到了一个重要的知识:滑动窗口,(卡尔老师的图片演示比我做的好,就看卡尔老师的图片演示就行,其中我的fast指针对应卡尔老师的j指针,我的slow指针对应卡尔老师的i指针),所谓滑动窗口和快慢指针差不多,我最开始的想法是这样的:用快慢指针slow和fast遍历这个数组,用一个整型变量sum保存每次子数组的求和结果,为了能够用一次for循环完成整个任务,我们必须在满足sum大于等于target(即题目要求的条件)后就将子数组缩小一个,即sum减去一个nums[slow],然后slow向前移动一个,直到sum不再大于等于target,我们才能够继续探索新的连续子数组(也就是for循环完成一次循环)。然后我们每次遇到符合条件的情况计算一次长度,长度为fast - slow + 1(fast和slow直接的元素个数),然后对比,初始化一个变量叫minlen,它的值是int32的最大值INT32_MAX,相当于一个无穷大,这样方便我们找最小值(如果找最大值,就赋值INT32_MIN),然后就对比,如果minlen没有fast - slow + 1小,就让minlen=fast - slow + 1,否则还是minlen,我们最后求的就是这个符合条件的最小长度的连续子数组的长度,如果没有合适的子数组,我们将返回0(即长度为0),其具体代码实现如下(顺利通过):

cpp 复制代码
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int slow = 0;
        int sum = 0; // 求和用的变量
        // (这个是错解)int len = 0; // 当前子数组的长度
        int minlen = INT32_MAX; //子数组的最小长度
        // slow先停着不动,fast正常遍历
        // sum每次都将fast遍历过的求和的元素保存起来
        // 我最开始的想法是想搞一个单独len变量记录长度
        // 但是这样会出错,假设数组是[1],target=7,根本找不到合适的子数组
        // 如果单独记录len的长度的变化,根据循环的条件
        // 这种情况,sum没有>=target,len是正常++的,也就是最后minlen=1
        // 所以不能用单独的变量len记录子数组长度
        // 子数组的长度其实是fast - slow + 1
        // 每次当sum>=target的时候,才对比minlen和fast - slow + 1
        // 如果某次循环,sum+=nums[fast];的值导致sum>=target
        // 此时刚好满足条件,先计算子数组长度,然后对比是否为最小的长度
        // 然后让sum-=nums[slow],把slow没移动前的元素剔除
        // 这样剔除一个元素后,继续判断(用while循环),直到不符合条件能够接着往下搜索子数组
        // 用while循环而不用if语句的原因是
        // 假设数组为[1,2,3,7,9],target=7,迭代到fast==3就满足了条件
        // 此时剔除slow指向的元素1,然后slow++
        // 新的子数组sum=2+3+7>7,还是满足条件,无法继续搜索子数组
        // 所以只能用while循环一直执行剔除和slow++,对比长度等操作
        // 直到不满足条件可以继续搜索子数组为止
        // 直到外层的for循环迭代结束,我们就遍历了所有符合条件的子数组
        for(int fast = 0; fast < nums.size(); fast++)
        {
            sum+=nums[fast];
            while(sum>=target)
            {
                minlen = min(fast - slow + 1, minlen);
                sum-=nums[slow];
                slow++;
            }
        }
        // minlen没有被赋值的话,说明没有合适条件的子数组
        if(minlen == INT32_MAX)
        {
            return 0;
        }
        return minlen;
    }
};

1.2 关于是用while循环还是if条件

我一开始的想法并没有在for循环里嵌套一个while(sum>=target)来完成这个过程,而是用的if(sum>=target),这就会导致一个问题:

如果数组nums[1, 2, 3, 7, 9],而target = 7,fast一直遍历到fast为3也就是其对应元素为7时,sum = 1 + 2 + 3 + 7 > 7,此时满足了条件,而fast为2时,sum=1 + 2 + 3=6 < 7不满足条件,如果在fast为3时,我们用的是if条件而不是while循环,那么,执行一次后sum减去nums[slow]=nums[0]=1就变成sum = 2 + 3 + 7>7,还是满足条件,但是我们用if只能执行一次,我们要找到不满足条件的时候才能进行下一次循环,所以我们只能用while循环来完成这个过程。

1.3 关于是用变量记录长度,还是用fast - slow + 1代表子数组的长度

我最开始的想法是用一个for循环外的遍历len来记录子数组的长度,fast每次增加,len++,如果不满足条件len--,直到不满足题目要求的条件,但是这样做是错的,比如nums为[1],而target为7,这种情况下,我们永远找不到满足条件的子数组,因为我们永远没法进入while循环条件,因为sum=1<7,所以我们也没法执行len--操作,这样就导致本应该返回0,现在却返回了错误的值1。

相关推荐
pianmian13 小时前
python数据结构基础(7)
数据结构·算法
好奇龙猫5 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
sp_fyf_20245 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
ChoSeitaku5 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程6 小时前
双向链表专题
数据结构
香菜大丸6 小时前
链表的归并排序
数据结构·算法·链表
jrrz08286 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time6 小时前
golang学习2
算法
@小博的博客6 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生7 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法