滑动窗口

滑动窗口解决哪种问题?
滑动窗口解决给定两个字符串S和T,问你S中是否存在一个子串,包含T中的所有字符并且不含有其他字符。

窗口右指针向右移动,窗口增大,直到满足条件,这时候找到可行解。
窗口左指针开始往右移动,窗口减小,开始搜寻最优解。

滑动窗口的代码逻辑:伪代码

int left = 0, right = 0;while (right < s.size()) {//增大窗口window.add(s[right]);right++;while (window needs  shrink) {//缩小窗口window.remove(s[left]);left++;}}

滑动窗口的代码框架

伪代码

void slidingWindow(string s, string t) {unordered_map<char, int> window, need;for(char c:t) need[c]++;//统计字符个数int left = 0, right = 0;int valid = 0;//窗口中满足need条件的字符个数while (right < s.size()) {//c是将移入窗口的字符char c = s[right];//右移窗口right++;//进行窗口内数据的一系列更新...//debug 输出的位置cout << "window: " << left << " " << right << endl;//判断左侧窗口是否要收缩while (window needs shrink) {//d是将要移出窗口的字符char d = s[left];//左移窗口left++;//进行窗口内一系列更新...}}
}

解释:unordered_map 是哈希表,实现键(key)值(value)映射,它的一个方法是count(key) 判断键key是否存在。

unordered_map<char, int> window, need;

window和need是计数器

  1. window记录窗口中字符的个数
  2. need记录所需要的字符长度

下面valid表示need中字符被满足的个数,比如need中字符a的数量有2个,在window中字符a的数量≥2时,valid的值会自增valid++。

valid==need.size() 的时候,证明字符串t中字符个数已满足,window左指针开始右移,进行窗口缩减。

使用滑动窗口模板解题

Leetcode76 最小覆盖子串

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。

示例:

输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

说明:

如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码

class Solution {public:string minWindow(string s, string t) {if(s.size()<t.size()) return "";//t中包含的字符更多unordered_map<char,int> window,need;for(int i=0;i<t.size();i++)//need哈希表初始化need[t[i]]++;int left=0,right=0;//前后指针int valid=0;//记录字符匹配的个数int start=0,len=INT_MAX;//最小字串的起始点,和长度while(right<s.size()){//右指针char p=s[right];//p在子串t中if(need.count(p)){window[p]++;if(window[p]==need[p])valid++;}right++;//确保右区间是开的,即左闭右开,方便计算right-left长度while(valid==need.size()){//满足最低个数要求,window中元素个数≥need中元素个数if(right-left<len){//最小覆盖子串len=right-left;start=left;}char q=s[left];//从窗口中除去left++;if(need.count(q)){if(window[q]==need[q])valid--;window[q]--;           }}}return len==INT_MAX ?"":s.substr(start,len);}
};

Leetcode567 字符串的排列

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
示例1:

输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).

示例2:

输入: s1= “ab” s2 = “eidboaoo”
输出: False

注意:

输入的字符串只包含小写字母
两个字符串的长度都在 [1, 10,000] 之间

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutation-in-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析
窗口缩减的时机是窗口大小等于 s1.size()时,这是因为排列和原字符串长度一致。
valid==need.size()时,子串合法

代码

class Solution {public:bool checkInclusion(string s1, string s2) {unordered_map<char,int> window,need;for(auto t:s1) need[t]++;int left=0, right=0;int valid=0;while(right<s2.size()){char c=s2[right];if(need.count(c)){window[c]++;if(window[c]==need[c]){valid++;}}right++;while(right-left>=s1.size()){if(valid==need.size())return true;char d=s2[left];if(need.count(d)){if(need[d]==window[d]){valid--;}window[d]--;}left++;}}return false;}
};

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

给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。

字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。

说明:

字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。

示例 1:

输入:
s: “cbaebabacd” p: “abc”

输出:
[0, 6]

解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的字母异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的字母异位词。

示例 2:

输入:
s: “abab” p: “ab”

输出:
[0, 1, 2]

解释:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的字母异位词。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的字母异位词。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的字母异位词。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析
异位词就是上面的排列,这里只需要更改返回符合条件的子串的下标

代码

class Solution {public:vector<int> findAnagrams(string s, string p) {if(s.size()==0) return {};vector<int> vec;unordered_map<char,int> need,window;for(int i=0;i<p.size();i++)need[p[i]]++;int left=0,right=0;int valid=0;while(right<s.size()){char c=s[right];if(need.count(c)){window[c]++;if(need[c]==window[c])valid++;}right++;while(right-left>=p.size()){if(valid==need.size()){vec.push_back(left);}char d=s[left];left++;if(need.count(d)){if(need[d]==window[d])valid--;window[d]--;}}}return vec;}
};

补充窗口简单题

Problem Description
有一个字符串S,该字符串只含有小写字母a-z,长度不大于100。

现在需要在S中寻找它的一个子字符串str,且str至少在S中出现过两次(字符串可以部分重叠,但是不能和子字符串str串完全重叠)。

计算一下这个子字符串str的最大长度是多少。

Input
输入一行字符串S(字符串的长度不大于100)

Output
输出子字符串str的最大长度

Sample Input:
ababa

Sample Output:
3

#include<iostream>
#include<map>
#include<string>
#include<cstdlib>//exit()using namespace std;map<string,int> mp;
string s;
int cnt;int main(){cin>>s;int len=s.size();int left=0,right=len-1;//倒数第二个字符 for(int i=len-1;i>0;i--){//控制长度 while(left<len&&left+i<=len){string tmp=s.substr(left,i);//长为i //cout<<tmp<<endl;mp[tmp]++;if(mp[tmp]>=2){cout<<i;    exit(0);}   left++;//窗口右移 }   left=0;//窗口位置 }return 0;
}

Leetcode双指针滑动窗口相关题目相关推荐

  1. 漫画:滑动窗口入门题目,没有之一

    今天是小浩算法"365刷题计划"第83天 .昨天写了一篇感悟,没想到那么受欢迎.几百人转发,好几千人阅读,虚荣心得到了极大的满足.今天继续为大家分享一道经典面试题目. 01 PAR ...

  2. 【LeetCode】重复元素相关题目

    [LeetCode]重复元素相关题目 文章目录 [LeetCode]重复元素相关题目 存在重复元素★ 存在重复元素 II★ 存在重复元素 III★★ 重复 N 次的元素★ 寻找重复数★★ 存在重复元素 ...

  3. 11. Leetcode 713. 乘积小于K的子数组 (数组-同向双指针-滑动窗口)

    给定一个正整数数组 nums和整数 k .请找出该数组内乘积小于 k 的连续的子数组的个数.示例 1:输入: nums = [10,5,2,6], k = 100 输出: 8 解释: 8个乘积小于10 ...

  4. LeetCode Hot100 ---- 滑动窗口专题

    什么是滑动窗口? 其实就是一个队列,比如题中的 abcabcbb找出其中不含有重复字符的 最长子串 的长度,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满 ...

  5. LeetCode 480. 滑动窗口中位数(大小堆升级版+set实现)

    1. 题目 中位数是有序序列最中间的那个数. 如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) ...

  6. LeetCode 239. 滑动窗口最大值(双端队列+单调栈)

    文章目录 1. 题目信息 2. 解题 2.1 暴力法 2.2 双端队列法 1. 题目信息 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内 ...

  7. 【小f的刷题笔记】(JS)双指针 - 滑动窗口 四类典型问题(附JS模版和详细注释代码)LeetCode76 LeetCode567 LeetCode438 LeetCode3

    [滑动窗口] JS模版 利用map对象建立滑动窗口,相关题目都可以通过套框架来解决 ✔ LeetCode76 最小覆盖子串 ✔ LeetCode567 字符串的排列 ✔ LeetCode438 找到字 ...

  8. leetcode ---双指针+滑动窗体

    一:Minimum Size Subarray Sum(最小长度子数组的和O(N)) 题目: Given an array of n positive integers and a positive ...

  9. LeetCode 239:滑动窗口最大值 思考分析

    给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 进阶: 你能在线性 ...

最新文章

  1. Spring Cloud-Honghu Cloud分布式微服务云系统(一)
  2. 民营企业的ERP之路
  3. FuncT,TResult的使用方法(转载)
  4. php中redis怎么使用,redis 怎么使用
  5. python字典随时添加元素和值
  6. 【转】TCP、UDP数据包大小的限制
  7. C++类的使用(六)—— 判断继承
  8. ubuntu 允许root用户登陆ssh
  9. data-sap-ui-icon-content where does icon content come from
  10. 一个程序猿必须掌握的HTML的常识
  11. codevs1380 没有上司的舞会
  12. centos7抢先安装docker1.0
  13. java游戏2333整合包,3dm游戏运行库合集离线安装包
  14. “开心网”10亿“卖身” !
  15. C# 串口接收的优化处理
  16. linux系统分辨率无法修改,Redhat9重新安装后无法修改分辨率
  17. 为什么Java程序员工资高?
  18. Windows 桌面主题 1.2
  19. 360浏览器兼容模式下js失效的问题
  20. 在centos7 下安装python3.6

热门文章

  1. GERBER文件格式简介
  2. 【项目经理之修炼(7)】《基础篇》人生游戏中的神器——谦虚
  3. 【控制】傅里叶系列(一)傅里叶级数 (Fourier series) 的推导
  4. Python Matplotlib 画图显示中文
  5. 3.10 候选区域-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  6. Ardino基础教程 22_PS2摇杆
  7. 2、C语言面试笔试---运算符和表达式
  8. 基础篇-verilog-FPGA实现频率相位调制DDS信号
  9. 4.Verilog 基础语法
  10. nodejs实现webservice问题总结