1.暴力法
求出s1的全排列,然后判断s2中是否包含s1的排列之一
代码如下:
class Solution {
public:
bool checkInclusion(string s1, string s2) {
//s2包含s1全排列中的一个
if(s2.size()<s1.size())
return false;
if(s2.find(s1)!=string::npos)
return true;
//确定s1的全排列
set<string> tem;
dfs(s1,0,tem);
vector<string> res(tem.begin(),tem.end());
for(int i=0;i<res.size();i++)
if(s2.find(res[i])!=string::npos)
return true;
return false;
}
//使用set为了防止s1中存在重复字母
void dfs(string s,int start,set<string>&tem)
{
if(start == s.size() - 1)
{
tem.insert(s);
return;
}
for(int i = start;i < s.size();i++)
{
swap(s[start],s[i]);
dfs(s,start + 1,tem);
swap(s[start],s[i]);
}
}
};
结果,超时
2.滑动窗口
维护一个大小为s1.size()的窗口,使用hashmap1记录字符串s1内的字符情况,hashmap2记录字符串s2中滑动窗口内的字符情况,当hashmap1==hashmap2时,则返回true
否则,取掉滑动窗口的第一个字符,然后统计滑动窗口之后的一个字符
代码如下:
class Solution {
public:
bool checkInclusion(string s1, string s2) {
if(s1.size()>s2.size())
return false;
int len=s1.size();//滑动窗口的大小
vector<int> hashmap1(26,0);
vector<int> hashmap2(26,0);
for(int i=0;i<len;i++)
{
hashmap1[s1[i]-'a']++;
hashmap2[s2[i]-'a']++;
}
for(int i=len;i<s2.size();i++)
{
if(hashmap1==hashmap2)
return true;
//否则,修改滑动窗口的值
hashmap2[s2[i-len]-'a']--;
hashmap2[s2[i]-'a']++;
}
return hashmap2==hashmap1;
}
};