滑动窗口经典例题之一——438. 找到字符串中所有字母异位词
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滑动窗口经典例题之一——438. 找到字符串中所有字母异位词相关的知识,希望对你有一定的参考价值。
题目
题目解析
一般滑动窗口问题也不多,LeetCode上能列举出来的例题似乎就这么多:
最小覆盖子串
而这些题的解题代码和思路几乎没有太大区别,就是以下这个套路:
void slidingWindow(string s,string t)
unordered_map<char,int> need,window;
for(char c:t)need[c]++;//更新需要的字符情况
int left = 0,right = 0;
int valid = 0;
while(right < s.size())
char c = s[right++];//右移窗口
/**对窗口内数据的一系列更新**/
...... //一般来说是根据need更新valid和window窗口
/**判断左窗口是否要收缩**/
*这里的收缩条件是重点
一般来说为以下两种收缩条件:
1.当窗口的长度大于等于答案需要的更新长度时。
对应:right-left >= t.size()
2.当窗口中已经包含了所有需要的字符时。
对应:valid >= need.size()
while(收缩条件)
1.进行是否是答案的判断并更新答案。
2.把左边的字符依次移出窗口,
如果该字符对valid产生影响则valid--。
- 这里的收缩条件是重点!
一般来说为以下两种收缩条件:
1. 当窗口的长度大于等于答案需要的更新长度时。
对应:right-left >= t.size()
一般用于答案为子串的情况。
2. 当窗口中已经包含了所有需要的字符时。
对应:valid >= need.size()
一般用于答案为子序列的情况。
- 当然还有其他多种收缩条件的情况,这个当然还得视情况而定(比如最长无重复子串的收缩条件应该为字符出现1次以上开始进行收缩)
代码对比:
最小覆盖子串(子序列问题的滑动窗口)
class Solution
public:
string minWindow(string s, string t)
unordered_map<char,int>need,window;
//更新need
for(char c:t)need[c]++;
int left = 0,right = 0;
//valid用于记录是否达到有效窗口处
int valid = 0;
//用于记录更新答案的相关信息
int start = 0,len = INT_MAX;
int size = s.size();
int size_n = need.size();
while(right<size)
//c是将移入窗口的字符
char c = s[right];
//右移窗口
right++;
//进行窗口内数据一系列更新
if(need.count(c))
window[c]++;
//表示该类字符已经被窗口包括
if(window[c]==need[c])
valid++;
//判断左窗口是否要收缩
while(valid==size_n)
//更新最小覆盖子串
if(right-left<len)
start = left;
len = right - left;
//d是将移出窗口的字符
char d = s[left];
//左移窗口
left++;
//进行窗口内数据的更新
if(need.count(d))
if(window[d]==need[d])
valid--;
window[d]--;
return len == INT_MAX?"":s.substr(start,len);
;
找所有字母异位词(子串问题的滑动窗口)
class Solution
public:
vector<int> findAnagrams(string s, string p)
int need[26]0; //p串需要的字符数目表
int count[26]0; //count计算当前窗口内已经记录的字符
int needSize = 0; //needSize为需要的不同字符情况
for (auto ch:p)
need[ch - 'a']++;
if (need[ch - 'a'] == 1)
needSize++;
;
int l, r; //左右指针
l = r = 0;
int sz = s.size();
int valid = 0; //记录有效的字符情况
vector<int> res;
while (r < sz)
char ch = s[r++];
if (need[ch - 'a']) //如果为所需的字符才将count++
count[ch - 'a']++;
if (need[ch - 'a'] == count[ch - 'a'])
valid++; //如果此时这个字符已经达到要求的数目,则valid++
/*收缩窗口*/
while (r-l >= p.size())
if (valid == needSize)//更新答案的又一限定条件:字符串长度相等
res.push_back(l);
char t = s[l++]; //窗口左移
if (need[t - 'a'])
if (count[t - 'a'] == need[t - 'a'])
valid--; //去字符过程中注意判断valid已经不符
count[t - 'a']--;
return res;
;
解题代码
class Solution
public:
vector<int> findAnagrams(string s, string p)
int need[26]0; //p串需要的字符数目表
int count[26]0; //count计算当前窗口内已经记录的字符
int needSize = 0; //needSize为需要的不同字符情况
for (auto ch:p)
need[ch - 'a']++;
if (need[ch - 'a'] == 1)
needSize++;
;
int l, r; //左右指针
l = r = 0;
int sz = s.size();
int valid = 0; //记录有效的字符情况
vector<int> res;
while (r < sz)
char ch = s[r++];
if (need[ch - 'a']) //如果为所需的字符才将count++
count[ch - 'a']++;
if (need[ch - 'a'] == count[ch - 'a'])
valid++; //如果此时这个字符已经达到要求的数目,则valid++
/*收缩窗口*/
while (r-l >= p.size())
if (valid == needSize)//更新答案的又一限定条件:字符串长度相等
res.push_back(l);
char t = s[l++]; //窗口左移
if (need[t - 'a'])
if (count[t - 'a'] == need[t - 'a'])
valid--; //去字符过程中注意判断valid已经不符
count[t - 'a']--;
return res;
;
以上是关于滑动窗口经典例题之一——438. 找到字符串中所有字母异位词的主要内容,如果未能解决你的问题,请参考以下文章