代码随想录 day2 | 209.长度最小的子数组

文档讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
看讲解前状态:不会
看讲解后状态:有思路
二刷状态:

基础知识:

  • int result = INT32_MAX;
    这行代码的作用是声明一个名为 result 的整数变量,并将其初始化为 32 位有符号整数的最大值。

    • INT32_MAX:这是C++标准库中定义的一个常量,表示 32 位有符号整数的最大值。它在头文件 <limits> 中定义,通常值为 2147483647,即 2^31 - 1。这个常量表示整数类型可以达到的最大值。
  • 这个操作可以用于在程序中设定一个初始值,然后在后续的计算或判断中进行比较,以确定更小的值。

题目:

https://leetcode.cn/problems/minimum-size-subarray-sum/

法一:暴力解法

代码实现:
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result  = INT32_MAX;
        int sum = 0;// 滑动窗口数值之和
        int i =0;// 滑动窗口的长度
        int subLength = 0;// 滑动窗口的长度
        for (int j=0;j<nums.size();j++){//j终止位置
            sum += nums[j];
            //使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
            while(sum>=target){
                subLength = (j-i+1);//子序列长度
                result = result < subLength ? result:subLength;
                sum -= nums[i++];//起始位置动态变化
            }
        }
        return result == INT32_MAX ? 0 :result; 
    }
};
时间复杂度:超时O(n^2)
空间复杂度:O(1)

法二:滑动窗口

解题关键:

  • 滑动窗口如何移动起始位置
  • for中循环的为终止指针

解题思路:

  • 不断的(用双指针)调节子序列的起始位置和终止位置,从而得出我们想要的结果。

  • for(j;j<=num.size;j++)

    • j为终止位置(若为起始位置,则与暴力解法无区别),起始位置需要动态移动。
  • 本题起始位置移动条件(动态方案):先计算[0,j]集合sum>target时,将终止位置固定住,再开始起始位置的移动。

    • 起始位置每次后移一位i++,每次sum-=nums[i],直到sum<target就不再移动i起始,保持在最后一次满足sum>target时的i处。然后终止位置往后移1位,然后i只需要往后移1位判断是否满足条件(sum>target),不满足就result保留上次subL,然后J继续后移,反复。
    • 这样I就不需要重复[0-i]的过程。
  • 每次更新的目标区间长度subL = j-i+1(终止-起始+1),

  • 最终结果最小区间长度result=min(result,subL),之前的result和本次更新的subL取最小值。

    • 所以result应该初始为MAX。因为只有当初始值为最大值时,才能每次都取小更新,最终取到所有subl最小值。
代码实现:
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result  = INT32_MAX;
        int sum = 0;// 滑动窗口数值之和
        int i =0;// 滑动窗口的长度
        int subLength = 0;// 滑动窗口的长度
        for (int j=0;j<nums.size();j++){//j终止位置
            sum += nums[j];
            //使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
            while(sum>=target){
                subLength = (j-i+1);//子序列长度
                result = result < subLength ? result:subLength;
                sum -= nums[i++];//起始位置动态变化
            }
        }
        return result == INT32_MAX ? 0 :result; 
    }
};
时间复杂度:O(n)
空间复杂度:O(1)

☹☹☹遇到的问题:

  • 滑动窗口时间复杂度为什么是O(n)?
    • 不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值