题目
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。换句话说,第一个字符串的排列之一是第二个字符串的子串。
示例1:
输入: s1 = "ab" s2 = "eidbaooo" 输出: True 解释: s2 包含 s1 的排列之一 ("ba").
示例2:
输入: s1= "ab" s2 = "eidboaoo" 输出: False
解题思路
滑动窗口+哈希
用一个26长度的数组记录字符串s1的哈希值,维护一个s1长度的滑动窗口,滑动窗口长度固定不变,每次向右移动一个单位,记录当前滑动窗口区间的哈希值,再与维护字符串s1的哈希值的数组比较。
AC代码
时间复杂度:O(n+m*n)
class Solution {
public:
int num[26];//维护字符串s1的哈希值
int ans[26];//维护滑动窗口的哈希值
bool checkInclusion(string s1, string s2) {
int n=s1.size();
for(int i=0;i<n;i++){
num[s1[i]-'a']++;
}
int l=0,r=n-1;
while(r<s2.size()){
//记录当前滑动窗口的哈希值
for(int i=l;i<=r;i++){
ans[s2[i]-'a']++;
}
int flag=1;
for(int i=0;i<n;i++){
if(ans[s1[i]-'a']!=num[s1[i]-'a']){
flag=0;
break;
}
}
//如果两数组哈希值相等,返回结果
if(flag){
return true;
}
//将记录当前滑动窗口的数组值清为0
for(int i=l;i<=r;i++){
ans[s2[i]-'a']=0;
}
//滑动窗口右移
l++;
r++;
}
return false;
}
};