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

滑动窗口,水果成篮 , 找到字符串中所有字母异位词 ,串联所有单词的子串

滑动窗口

滑动窗口(Sliding Window)是一种在计算机科学中用于解决各种子数组或子字符串问题的技术。滑动窗口技术通过维护一个固定大小的窗口在数组或字符串上移动,从而使得可以在较短的时间内解决一些复杂的问题。这种方法在处理一系列数据时特别高效。滑动窗口(Sliding Window)是一种在计算机科学中用于解决各种子数组或子字符串问题的技术。滑动窗口技术通过维护一个固定大小的窗口在数组或字符串上移动,从而使得可以在较短的时间内解决一些复杂的问题。这种方法在处理一系列数据时特别高效。

在这里插入图片描述

滑动窗口其实可以理解为一个左指针和一个右指针共同维护的一个区间,然后一起移动,这个区间的长度可能是不变的,也可能是变化的。

滑动窗口的几个基本步骤:

  1. 进窗口
  2. 判断
  3. 出窗口并更新结果

接下来我们用几道题来演示滑动窗口这个算法。

1. 水果成篮

题目链接

在这里插入图片描述
滑动窗口的几个基本步骤:

  1. 进窗口条件 : 因为题目中1 <= fruits.length <= 10^5,故建立int hash[100001] = {0}; 来标记每种树进了多少,并且需要一个count来记录hash表中有几种树
    进窗口的条件和判断的条件有关(这样想不容易把进窗口条件想复杂),这里是if(hash[fruits[right]] == 0) count++; //计数++
    hash[fruits[right]]++;//进窗口
  2. 判断 : 题目可得当 count > 2进入循环, 说明有两种以上的树被标记,在循环里面我们要判断 出窗口条件 和 什么时候更新数据
  3. 出窗口并更新结果 : hash[fruits[left]]–;//出窗口
    if(hash[fruits[left]] == 0) count–;//计数–
    left++;; 出判断循环里面后更新结果。
class Solution {
public:int totalFruit(vector<int>& fruits) {int hash[100001] = {0};//标记int left = 0, right = 0;int count = 0; //统计hash里面个数int ret = 0;while(right < fruits.size()){if(hash[fruits[right]] == 0) count++; //计数++hash[fruits[right]]++;//进窗口while(count > 2)//判断{hash[fruits[left]]--;//出窗口if(hash[fruits[left]] == 0) count--;//计数--left++;}ret = max(ret,right-left+1);//更新结果right++;}return ret;}
};

2. 找到字符串中所有字母异位词

题目链接

在这里插入图片描述
滑动窗口的几个基本步骤:

  1. 进窗口条件 :和上一道题很相似,但是这个需要两个标记hash数组, 用 int count = 0; //s中的滑动窗口 和 p有几个字符相等
    来判断 s中的滑动窗口 和 p有几个字符相等
    进窗口的条件和判断的条件有关(这样想不容易把进窗口条件想复杂),这里是hash2[s[right]]++;//进窗口
    if(hash2[s[right]] <= hash1[s[right]]) count++; //计数++
  2. 判断 : 题目可得当 if(right - left + 1 > p.size())//判断, 这是定长滑动窗口, 说明窗口长度超过p字符串长度,里面我们要判断 出窗口条件 和 什么时候更新数据
  3. 出窗口并更新结果 : if(hash2[s[left]] <= hash1[s[left]]) count–; //计数–
    hash2[s[left]]–;//出窗口
    left++;; 出判断循环里面后更新结果。

注意 : 计数-- 操作需要在出窗口之前, 举例 :s = “abac” , p = ‘’ ac "; 第二次进入if判断里面 ,定长窗口暂时为【bac】,
如果先 hash2[s[left]]–;的话,那个b存的hash值就变为0,然后判断 if(hash2[s[left]] <= hash1[s[left]]) count–; 就会成立,然后count就会–; 但是count是s中的滑动窗口 和 p有几个字符相等 , 这里并不相等,所以就会出错。

class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> v;int hash1[128] = {0}; //标记pint hash2[128] = {0}; //标记sfor(auto ch : p){hash1[ch]++;}int left = 0, right = 0;int count = 0; //s中的滑动窗口 和 p有几个字符相等int ret = 0;while(right < s.size()){hash2[s[right]]++;//进窗口if(hash2[s[right]] <= hash1[s[right]]) count++; //计数++if(right - left + 1 > p.size())//判断, 这是定长滑动窗口{if(hash2[s[left]] <= hash1[s[left]]) count--; //计数--hash2[s[left]]--;//出窗口left++;}if(count == p.size())v.push_back(left);right++;}return v;}
};

3. 串联所有单词的子串

题目链接

在这里插入图片描述

这道题和 2 题一样,只不过2题是字母, 而这个每个字母都变成了字符串

变化:

  1. 滑动窗口需要执行的次数 : 3
    在这里插入图片描述

  2. left 和 right的移动

移动的步长 为 单词的长度

class Solution {
public:vector<int> findSubstring(string s, vector<string>& words) {vector<int> v;unordered_map<string,int> hash1;for(auto s : words)hash1[s]++;int len = words[0].size();for(int i = 0; i < len; i++){int left = i, right = i;int count = 0;unordered_map<string,int> hash2;while(right < s.size()){hash2[s.substr(right,len)]++; //进窗口if(hash2[s.substr(right,len)] <= hash1[s.substr(right,len)])count++;while(right - left + 1 > len * words.size())//判断 , 定长滑动窗口{if(hash2[s.substr(left,len)] <= hash1[s.substr(left,len)]) //出窗口count--;hash2[s.substr(left,len)]--;left+=len;}if(count == words.size()) // 更新数据v.push_back(left);right+=len;}}return v;}
};

http://www.mrgr.cn/news/54976.html

相关文章:

  • Vue2、Vue3温习解惑知识点
  • 【MySQL】提高篇—事务管理:事务隔离级别的介绍
  • 数据库、数据仓库、数据湖和数据中台有什么区别
  • 大数据学习-Clickhouse
  • 有同学问:拿到大厂JAVA OFFER,但是会不会不稳定,有失业风险?!
  • process.exit 作用
  • 练习题 - Scrapy爬虫框架 Selectors 数据选择器
  • 权限管理系统的详细解析与实现
  • 栈与队列的常见接口的实现
  • yolov8实例分隔
  • OpenCV图像处理——查找线条的转折点
  • 鸿蒙中富文本编辑与展示
  • Guava防击穿回源-同步防击穿
  • 数据结构7——二叉树的顺序结构以及堆的实现
  • jupyter notebook中执行过程中更新模块代码,再执行没有更新执行
  • 机器学习与神经网络:诺贝尔物理学奖的新纪元
  • Vue中使用路由
  • 数据结构:二叉树、堆
  • python+Mosh网课笔记04
  • 计算机毕业设计 基于java个性化智能学习系统的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
  • 关于SSD1306的OLED的显示的研究
  • 一图秒懂色彩空间和色彩模型
  • 云计算-----单机LNMP结构WordPress网站
  • 从DexMV、VideoDex、MimicPlay到SeeDo:从人类视频中学习:机器人的主流训练方法之一
  • 网盘直链下载神器NDM
  • Springboot指定扫描路径