给你两个字符串 s1
和 s2
,写一个函数来判断 s2
是否包含 s1
的排列。
换句话说,s1
的排列之一是 s2
的 子串 。
示例 1:
输入:s1 = "ab" s2 = "eidbaooo" 输出:true 解释:s2 包含 s1 的排列之一 ("ba").
示例 2:
输入:s1= "ab" s2 = "eidboaoo" 输出:false 提示:
1 <= s1.length, s2.length <= 104
s1
和s2
仅包含小写字母
由于排列不会改变字符串中每个字符的个数,所以只有当两个字符串每个字符的个数均相等时,一个字符串才是另一个字符串的排列。
滑动窗口1(4ms)
class Solution {
public:
bool checkInclusion(string s1, string s2) {
vector<int>temp1(26) ;
vector<int>temp2(26) ;
int L1 = s1.size(),L2 = s2.size();
if(L1 > L2)
return false ;
for( int i = 0;i < L1 ;++i){
temp1[s1[i]-'a']++;
temp2[s2[i]-'a']++ ;
}
if( temp1 == temp2)
return true ;
for( int i = L1;i < L2 ;++i){
temp2[s2[i-L1] - 'a']-- ;
temp2[s2[i] - 'a'] ++ ;
if(temp1 == temp2)
return true ;
}
return false ;
}
};
滑动窗口2(4ms)
class Solution {
public:
bool checkInclusion(string s1, string s2) {
int Len1 = s1.size(), Len2 = s2.size();
if( Len2 < Len1)
return false ;
vector<int>Cnt(26);
int Diff = 0 ;
for( int i = 0;i < Len1 ; ++i){
--Cnt[s1[i] - 'a'];
++Cnt[s2[i] - 'a'] ;
}
for( int C :Cnt){
if( C )
Diff++ ;
}
if( Diff == 0)
return true ;
for( int i = Len1;i < Len2 ;++i){
int X = s2[i] - 'a',Y = s2[i-Len1] - 'a';
if(X == Y)
continue ;
if( Cnt[X] == 0 )
Diff++ ;
++Cnt[X] ;
if( Cnt[X] == 0)
Diff-- ;
if(Cnt[Y] == 0)
Diff++ ;
--Cnt[Y];
if(Cnt[Y] == 0)
Diff-- ;
if( Diff == 0)
return true ;
}
return false ;
}
};
评价与理解:解法2需要仔细思考