C++手撕LeetCode——双指针(滑动窗口)

文章介绍了滑动窗口算法的关键思路,包括在处理数组和字符串问题中的应用,以及它的优点:低时间复杂度、低空间复杂度和良好的可读性。作者通过3.1209题为例,展示了如何使用滑动窗口找到和大于等于目标值的最小子数组,并提供了C++代码实现。此外,文章还提及了作者利用此方法备战秋招和实习面试的情况。
摘要由CSDN通过智能技术生成

    大三寒假要结束了,继续备战秋招,年前刷了些双指针、数组、链表的简单LeetCode题,都没有做笔记,现在也忘得差不多了,计划写一份专栏记录刷题的过程,复盘算法中的细节,由易到难,先刷简单题,再斩中等题!  


        一转眼就到4月份了,投递了好多暑期实习,4月份笔面试就会陆续开启,距离秋招也越来越近,这段时间在刷LeetCode Hot 100,每天刷个两道mid题,同时作个笔记,作为复盘,也作为到时笔面试前的复习资料

目录

一、关键思路:双指针-滑动窗口法

二、滑动窗口法优点       

三、例题训练

3.1 209. 长度最小的子数组


一、关键思路:双指针-滑动窗口法

     滑动窗口法是一种常用的算法技巧,它通常用于数组或字符串的遍历,以及子串或子序列的搜索等问题。该算法的基本思想是维护一个滑动窗口,每次移动窗口,通过更新窗口的左右边界,来得到新的结果。具体来说,滑动窗口算法通常包含以下几个步骤:

  1. 初始化窗口左右边界,例如 left=0, right=0。
  2. 移动右边界,直到满足某个条件,例如窗口内元素的和等于目标值。
  3. 移动左边界,直到不满足条件,同时更新结果,例如记录最小窗口长度。
  4. 重复步骤 2 和步骤 3,直到右边界到达数组或字符串的末尾。

二、滑动窗口法优点       

滑动窗口算法的优点包括:

  1. 时间复杂度较低:滑动窗口算法通常只需要遍历一次数组或字符串,因此时间复杂度为 O(n)。
  2. 空间复杂度较低:滑动窗口算法通常只需要维护常数个变量,因此空间复杂度为 O(1)。
  3. 可扩展性强:滑动窗口算法通常可以很容易地扩展到多维数组或多个字符串的问题中。
  4. 可读性强:滑动窗口算法的思路简单,代码实现也比较容易理解。

三、例题训练

3.1 209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。


示例 1:

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-size-subarray-sum

  • 实现思路:

        具体实现时,我们可以用两个指针来表示滑动窗口的左右端点,

1. 初始化时两个指针都指向数组的起始位置;

2. 然后,我们不断移动右指针,直到子数组的和大于等于 target,此时更新答案;

3. 然后移动左指针,缩小子数组的范围,直到子数组的和小于 target;

4. 然后再移动右指针,重复这个过程,直到右指针移动到数组的末尾。

        时间复杂度为O(n),其中n为数组的长度。因为每个元素最多被访问两次,一次是被右指针访问到,一次是被左指针访问到。空间复杂度为O(1),因为我们只需要维护常数个变量。

  • 核心思路:

        每一轮迭代,将 nums[right] 加到 sum,如果 sum > target,则更新子数组的最小长度 (此时子数组的长度是right- left+1),然后将nums[left] 从 sum中减去并将 left右移,直到 sum< target,在过程中同样更新了数组的最小长度。在每一轮迭代的最后,将 right右移

 for(int right=0;right<len;right++)
        {
            res+=nums[right];
            while(res>=target)
            {
                int curlen=right-left+1;
                minlen = curlen<minlen?curlen:minlen;
                res-=nums[left++];   
            }
        }
  • C++代码实现:
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        int res=0;
        int minlen=INT32_MAX;
        int left=0;
        int len =nums.size();
        for(int right=0;right<len;right++)
        {
            res+=nums[right];
            while(res>=target)
            {
                int curlen=right-left+1;
                minlen = curlen<minlen?curlen:minlen;
                res-=nums[left++];   
            }
        }
        return minlen == INT32_MAX ? 0 : minlen;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值