给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
换句话说,s1 的排列之一是 s2 的子串 。
- 示例
输入:s1 = "ab" s2 = "eidbaooo"
输出:true
解释:s2 包含 s1 的排列之一 ("ba").
思路
看到子串匹配问题,首先想到滑动窗口。之前讲过 滑动窗口算法 的套路,忘记的小伙伴可以再去看一下。接下来直接套用模板来解决这道题。
PS : 今天使用C++来写这道题,因为 C++ 对map的操作更简洁,更加易懂。
- 代码
bool checkInclusion(string s1, string s2) {
unordered_map<char,int>need, window;
for (char c : s1)
need[c]++;
int left=0,right=0;
//表示满足need条件的字符个数
int vaild = 0;
while (right< s2.size()){
//进入窗口的字符
char c = s2[right];
right++;
//对窗口内数据进行处理
//need包含字符c,更新数据
if (need.count(c)){
window[c]++;
if (window[c]==need[c]){
vaild++;
}
}
//判断左侧窗口是否要收缩(当窗口大于等于s1长度时,进行收缩)
//滑动窗口的关键就在于判断什么时候进行收缩
while (right-left>=s1.size()){
if (vaild==need.size())
return true;
char d = s2[left];
left++;
//更新窗口中的数据
if (need.count(d)){
if (window[d]==need[d])
vaild--;
window[d]--;
}
}
}
return false;
}