当前位置: 首页 > ai >正文

【专刷】滑动窗口(一)

📝前言说明:

  • 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分
  • 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话)
  • 文章中的理解仅为个人理解。如有错误,感谢纠错

🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux
🎀CSDN主页 愚润泽

视频

  • 滑动窗口的关键
  • 209. 长度最小的子数组
    • 个人解
    • 深刻理解滑动窗口
  • 3. 无重复字符的最长子串
    • 个人解
  • 1004. 最大连续1的个数 III
    • 个人解
  • 1658. 将 x 减到 0 的最小操作数
    • 个人解
    • 优质解:


滑动窗口的关键

滑动窗口:同向双指针(即leftright移动方向相同,且right不回退)

滑动窗口是:通过动态调整窗口的左右边界来避免重复计算,从而降低时间复杂度。
其核心思想是维护一个窗口,通过移动右边界扩展窗口、移动左边界收缩窗口,找到满足条件的解。(窗口的状态始终要满足条件)

滑动窗口前提:

  1. 同向双指针
  2. 操作的窗口是连续子数组
  3. 有“单调性”,这种单调是指:可以根据窗口来推出其他的子数组是否满足条件,如:在一个非负数组里面找子数组,如果窗口内的值之和>target,则right往右移动,更大的窗口内的值之和肯定也大于target

代码要点:

  1. leftright标记窗口的左区间和右区间
  2. 进窗口(更新要维护的值)
  3. 判断(新元素进窗口后,维护的值怎么变化),由判断结果决定:出窗口(弄清楚判断满足什么条件的时候,需要出窗口
  4. 更新结果(就题论题,有些是出窗口更新结果,有些是判断的时候更新)

进出窗口是:左右指针的移动

209. 长度最小的子数组

个人解

思路:
本题维护的是子数组内元素的和sum,当sum >= target的时候就可以更新结果,然后出窗口,当不满足条件的时候需要进窗口。

屎山代码:

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size(), ans = n + 1, sum = 0; // sum 是要维护的值for(int left = 0, right = 0; right < n; right++){sum += nums[right]; // 进窗口while(sum >= target) // 判断{ans = min(right - left + 1, ans); // 更新结果sum -= nums[left++]; // 出窗口}}return ans <= n ? ans : 0;}
};

时间复杂度:O(n)
空间复杂度:O(1)


深刻理解滑动窗口

我们通过这道题再剖析一下滑动窗口,这道题为什么能使用滑动窗口,从暴力解法到滑动窗口的优化。

暴力解法
left从左向右遍历数组,right在每个left下,再遍历数组,获得每个子数组的信息。时间复杂度O( n 2 n^2 n2)

如何优化成滑动窗口?

请添加图片描述
滑动窗口的正确性就是:单调性保证的,利用单调性规避了很多没有必要的枚举!


3. 无重复字符的最长子串

个人解

思路:
维护(判断):窗口内的每个字符出现个数不超过 1
因为本题是找最长:所以,满足条件的时候尽可能的进窗口。
而上一题,是找最短,所以当满足条件的时候是出窗口。

用时:5:00
屎山代码:

class Solution {
public:int lengthOfLongestSubstring(string s) {int n = s.size(), ans = 0;map<char, int> cnt;for(int left = 0, right = 0; right < n; right++){cnt[s[right]]++; // 进窗口while(cnt[s[right]] > 1) // 判断{cnt[s[left]]--;left++; // 出窗口}ans = max(ans, right - left + 1); // 更新结果}return ans;}
};

时间复杂度:O(n)
空间复杂度:O(1)


1004. 最大连续1的个数 III

个人解

思路:

  • 维护变量:窗口内的0的个数要<=k
  • 进窗口:进窗口时更新窗口内变量的值(通过判断进入的是不是0)
  • 判断(出窗口操作一般依托于判断):什么时候需要出窗口?当窗口内的数量大于k,所以这就是判断条件
  • 出窗口:随着判断也就顺便完成了。出窗口时也需要更新窗口内维护的变量的值。
  • 更新变量:因为判断的是不满足的条件,所以在出窗口后更新(出窗口后一定满足条件)

用时:6:48
屎山代码:

class Solution {
public:int longestOnes(vector<int>& nums, int k) {int ans = 0, n = nums.size(), len = 0;for(int left = 0, right = 0; right < n; right++){if(nums[right] == 0){k--;}len += 1; // 进窗口while(k < 0) // 判断{if(nums[left] == 0){k++;}left++; // 出窗口len--;}ans = max(len, ans);}return ans;}
};

时间复杂度:O(n)
空间复杂度:O(1)


1658. 将 x 减到 0 的最小操作数

个人解

思路:
将题目转换成:求满足元素和==target的最长子数组
先对数组元素求和sum。然后target == sum - x
用时:13:00
屎山代码:

class Solution {
public:int minOperations(vector<int>& nums, int x) {int target = std::accumulate(nums.begin(), nums.end(),0) - x;if(target < 0){return -1;}if(target == 0){return nums.size();}int n = nums.size(), sum = 0, len = 0;for(int left = 0, right = 0; right < n; right++){sum += nums[right]; // 入窗口while(sum >= target) // 判断{if(sum == target){len = max(right - left + 1, len); // 更新结果}sum -= nums[left]; // 出窗口left++;}}return len == 0 ? -1 : n - len; }
};

时间复杂度:O(n)
空间复杂度:O(1)


优质解:

看了一下别人的题解,用滑动窗口的也是这种逆向思维转换一下。


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

http://www.xdnf.cn/news/408.html

相关文章:

  • CasualLanguage Model和Seq2Seq模型的区别
  • Day2—3:前端项目uniapp壁纸实战
  • MCP 协议——AI 世界的“USB-C 接口”:解锁智能协作的新时代
  • Linux(autoDL云服务器)mamba-ssm环境安装——一次成功!
  • [Java EE] Spring AOP 和 事务
  • 2025.04.19-阿里淘天春招算法岗笔试-第三题
  • C++——异常
  • 【正则表达式】正则表达式使用总结
  • QML动画--ParallelAnimation和SequentialAnimation
  • 《AI大模型应知应会100篇》第27篇:模型温度参数调节:控制创造性与确定性
  • springboot--web开发请求参数接收注解
  • QML Label 组件
  • sqlilabs-Less11 POST注入
  • 【STM32单片机】#10 USART串口通信
  • Linux 进程间通信详解
  • 【Cheat Engine】官方教程步骤8:多级指针 超详解!
  • 玩转Docker | 使用Docker部署tududi任务管理工具
  • 面向对象设计中的类的分类:实体类、控制类和边界类
  • Serving入门
  • B端管理系统:企业运营的智慧大脑,精准指挥
  • STM32的三种启动方式
  • Rsync+sersync2实现目录实时同步
  • 《解锁图像“高清密码”:超分辨率重建之路》
  • llama-factory微调报错:
  • MySQL——触发器
  • 使用C语言的cJSON中给JSON字符串添加转义
  • 7.vtk坐标系
  • 爬取B站视频弹幕的简易教程(下)
  • c++_csp-j算法 (1)
  • Win 11 重装 Ubuntu 双系统方法