567. 字符串的排列
题目描述
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
换句话说,s1 的排列之一是 s2 的 子串 。
示例 1 :
输入:s1 = "ab" s2 = "eidbaooo"
输出:true
解释:s2 包含 s1 的排列之一 ("ba").
示例 2:
输入:s1= "ab" s2 = "eidboaoo"
输出:false
滑动窗口 :
我们的任务是要找到s2中的s1字串的任意排列,那么相当于我们只需要在s2中找到一个窗口,这个窗口的各个字符数量跟s1的各个字符数量一样。
为此,我们可以创建两个窗口,一个不做修改直接指向s1的全体字符,另一个跟着s2遍历。每遍历一次比较一次大小。
bool checkInclusion(string s1, string s2) {
int m = s1.length(), n = s2.length();
// 我们要找的是s2中有没有s1的字串,s2如果还没有s1大直接就false了
if(m>n){
return false;
}
// 对于vector而言,如果类型为c++基础类型,可以直接用==进行比较,内部已经重构了运算符。
// 如果这里用的int数组,就需要注意,直接用==比较的是各个数组的地址,程序会出问题。
vector<int> ctn1(26);
vector<int> ctn2(26);
// 先同步扩充两个滑动窗口的大小
for(int i=0;i<m;i++){
ctn1[s1[i]-'a']++;
ctn2[s2[i]-'a']++;
}
if (ctn1==ctn2){
return true;
}
for(int i=m;i<n;i++){
// 左出右进
ctn2[s2[i]-'a']++;
ctn2[s2[i-m]-'a']--;
if(ctn1==ctn2){
return true;
}
}
return false;
}
改进