-
滑动窗口法
不加任何优化,直接在s2中划定一个大小为s1的窗口,然后通过排序比较的方法向后比较。
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
bool checkInclusion(string s1, string s2) {
int len1=s1.size(),len2=s2.size();
if(len1>len2)
return false;
int left=0,right=len1-1; //确定滑动窗口的左右边界
sort(s1.begin(),s1.end()); //排序
while(right<len2)
{
string str=s2.substr(left,right-left+1); //substr(pos,n) 从pos开始n个字符
sort(str.begin(),str.end());
if(s1==str) return true;
else
{
right++;
left++;
}
}
return false;
}
int main()
{
string str1="ab";
string str2="sdasbadsa";
if(checkInclusion(str1,str2))
cout<<"yes";
else
cout<<"no";
return 0;
}
虽然通过了但是很惨淡。
优化一下
bool checkInclusion(string s1, string s2) {
int len1 = s1.size(), len2 = s2.size();
if (len1 > len2)
return false;
vector<int> str1(26), str2(26),str(26); //用来存储s1 s2中字符出现的次数
for (auto s : s1)
str1[s - 'a']++; //初始化 str1 str2 数组
for (int n = 0; n < len1; n++)
str2[s2[n] - 'a']++;
int left = 0, right = len1 - 1;
while (right < len2)
{
if (str1 == str2) //判断是否一致,这里应该还能优化
return true;
right++;
if (right >= len2) return false;
if (str1[s2[right] - 'a'] == 0) //这里判断了一下当前字符是否在s1中出现
{ //如果没有的话可以直接从该字符后面开始
if (right + len1 >= len2)
return false;
else
{
left = right + 1;
right = left + len1-1; //把窗口移到该字符后
str2 = str;
for (int n = left; n <= right; n++)
str2[s2[n] - 'a']++;
}
}
else
{ //正常情况 左边出 右边进
str2[s2[right] - 'a']++;
str2[s2[left] - 'a']--;
left++;
}
}
return false;
}
int main()
{
string str1="ab";
string str2="aaaaacbdadada";
if(checkInclusion(str1,str2))
cout<<"yes";
else
cout<<"no";
return 0;
}
还可以 下次继续优化