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

算法:滑动窗口类型题目的总结

前言

最近在复习算法的时候,发现滑动窗口类型的题目好像在写代码的时候有很强的共性,
多尝试了几道题,发现,诶,好像还真行。
于是,赶紧分享出来给大家看看,到底这个模版行不行,大家一起检查检查,看看有没有问题。

下面,我们先来看几道题目。

题目一:无重复字符的最长子串

在这里插入图片描述
题目链接:无重复字符的最长子串

思路:
我们用双指针围出来一个滑动窗口,同时利用哈希表记录下窗口中每个字母的个数
保证这个窗口里所有的字母的个数都是1,
一旦超过1了,就要出窗口,
怎么出窗口呢?
当然是left指针右移,当然右移之前,需要将记录的left位置的字母的个数减一。

每次循环,都检测一次窗口长度,一旦窗口长度比记录的最长长度还大,就立即更新,
最后返回记录的最大窗口大小。

代码:

int lengthOfLongestSubstring(string s) {int hash[128] = {0};int left = 0,right = 0;int len = 0;//首先right < s.size()while(right < s.size()){//入窗口 hash[s[right]]++;//判断是否需要出窗口while(left <= right && hash[s[right]] > 1){//出窗口hash[s[left++]]--;}//right此处右移right++;//更新窗口大小len = max(len,right - left);}//返回值return len;}

哇,看完第一题就套路拉满了。

题目二:最大连续1的个数 III

题目:
在这里插入图片描述
题目链接:最大连续1的个数 III

思路:
我们不需要管什么翻转,鬼知道小于k个,最多要翻转多少个,
我们直接转换思路,
我们需要寻找一个长度最长的区间,这个区间里面0的个数最多为k

依旧滑动窗口,用双指针围出来一个窗口,这个窗口就是我们要寻找的区间,我们保证区间里面0的个数不超过k。

来了一个数字,不管是1还是0,先入窗口再说,
接着判断是否需要出窗口,
如果需要出窗口,就对left进行右移,同时遇到0了,减去区间里面的0的个数,
不管需不需要出窗口,right都需要右移

同时,每次循环的的最后,都要计算窗口大小,并决定是否需要更新,

最后返回最大的窗口大小即可。

代码:

int longestOnes(vector<int>& nums, int k) {int left = 0,right = 0;int len = 0;int count = 0;//老样子,right < nums.size()while(right < nums.size()){//入窗口if(nums[right] == 0)count++;//判断是否需要出窗口while(left <= right && count > k){//出窗口if(nums[left++] == 0)count--;}//right++right++;//更新窗口大小len = max(len,right - left);}//返回最大的窗口大小return len;}

真的,完全一摸一样的套路啊

题目三:将 x 减到 0 的最小操作数

题目:
在这里插入图片描述
题目链接:将 x 减到 0 的最小操作数

思路:
第一反应肯定是搜索,但是搜索在这个题目时间复杂度实在是太夸张了,显然不可能。

接着思考,想了半天,哇,怎么这么难,稍微瞄一眼答案,发现这个题目需要进行一次题意转换。
正着想实在是太麻烦了,不知道究竟需要调整哪一端,
而如果我们逆向思维,直接计算中间的和。

这道题目要求我们计算左边一段区间和右边一段区间的和为x,
那么整个数字的和 - x 不就等于 中间一段区间的和了吗?
要求最小操作次数,那么我们中间这段区间的长度就要尽可能长。

所以题意就转化成了寻找一段最长的区间,使得这段区间的和为 sum - x。

还是滑动窗口,找到一个窗口使得窗口和 == sum - x。

代码:

int minOperations(vector<int>& nums, int x) {//正难则反,//两端不好算,我们算中间,//两端的和要等与x//中间的和就等于 sum - x//也就是要求找一段区间,要长度最长,且区间和 == sum - x;int sum = 0; for(auto& e :nums){sum+=e;}int ret = sum - x;int left = 0,right = 0;int tmp = 0;int len = -1;//老样子,right < nums.size()while(right < nums.size()){//入窗口tmp += nums[right];//必须要加上left <= right的限制,不然会越界//判断是否需要出窗口while(tmp > ret && left <= right){//出窗口tmp -= nums[left++];}//right++right++;//更新窗口大小if(tmp == ret)len = max(len,right - left);}//返回最后的符合要求的窗口大小return len == -1 ? -1 : nums.size() - len;}

真有规律吧!!!

模版总结

一旦我们发现一道题目可以用滑动窗口的思路结局,那么这道题就可以按照下面的步骤写,

首先,定义好left,right,并且定义好其他的用于记录的变量,
接着,right < nums.size() 进行循环
再然后,进窗口
再然后写一个while循环来判断是否需要出窗口
在while循环里面写上出窗口的逻辑,一般都是某某–,left++
出了while循环,无论是否需要出窗口,right都要++
每次循环都要更新窗口大小
最后返回合适的窗口大小即可

http://www.dtcms.com/a/545851.html

相关文章:

  • 广告公司宣传语深圳免费网站排名优化
  • zabbix监控
  • 禁用Spring Boot 中邮件健康检查
  • 基于Prometheus和Grafana的MySQL监控,服务器监控
  • 电子商务网站开发流程包括国外域名注册商排名
  • 手机如何做微商城网站设计微信里面如何做网站
  • 大模型-模型压缩:量化、剪枝、蒸馏、二值化 (5)
  • Apollo的inner message和proto message以及同一进程里有多个线程传递两种不同消息数据时可能导致进程崩溃
  • 做响应式网站的菜单栏网上做兼职的网站有哪些
  • 六安seo网站推广报价wordpress蜘蛛插件
  • DDR功能拓展之NVME数据处理
  • 中国建设银行官方网站悦生活长沙专业网站设计
  • Rust——异步递归深度指南:从问题到解决方案
  • 做网站要买什么空间网站创建快捷方式
  • wordpress网站管理系统威海住房和城乡建设局网站首页
  • 8.1.1 大数据方法论与实践指南-埋点需求流程
  • 【实时Linux实战系列】实时Linux项目的文档化与知识传递
  • 电子商务网站开发参考文献购物网站开发的必要性
  • web端 F12 快捷修改请求参数并重发接口
  • 东莞网站建设乐云seo在线制作公众号一键导入wordpress
  • Promise.all和Promise.race的区别
  • 聊城有制作网站的吗甘肃建设厅网站首页
  • 思维类:如何让孩子喜欢阅读
  • 如何编写网站建设销售的心得近10天的时政新闻
  • 百度亮相 SREcon25:搜索稳定背后的秘密,微服务雪崩故障防范
  • 仓颉语言中的MVVM架构实现:响应式数据绑定底层机制深度解析
  • PHP7.4.33 安装sqlsrv扩展
  • 哪个公司要做网络推广常德seo快速排名
  • 置换-选择排序:外存排序的艺术与智慧
  • 遗传算法全局寻优ETF动态止盈参数空间的新范式