给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
换句话说,s1 的排列之一是 s2 的 子串 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutation-in-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
public class Solution{
public boolean checkInclusion(String s1,String s2){
char[] pattern=s1.toCharArray();
char[] text=s2.toCharArray();
int pLen=s1.length();
int tLen=s2.length();
int[] pFreq=new int[26]; //记录s1字符出现的频率
int[] winFreq=new int[26]; //记录移动数组字符串每隔字母出现的频率
for(int i=0;i<pLen;i++){
pFreq[pattern[i]-'a']++;
}
int pCount=0; // s1字符种类个数,比如abb,就是2,有两个字母
for(int i=0;i<26;i++){
if(pFreq[i]>0){
pCount++;
}
}
int right=0,left=0;
//当滑动窗口中的某个字符个数与 s1 中对应相等的时候才计数
int winCount=0; //移动数组字符串出现的种类个数
while(right<tLen){
if(pFreq[text[right]-'a']>0){ //如果right上的字符是pFreq上出现过的
winFreq[text[right]-'a']++; //那么移动数组的上该字母出现的频数先加一
if(pFreq[text[right]-'a']==winFreq[text[right]-'a']){
winCount++; /*如果移动数组上的该字符的频数与s1相等,那么就
winCount字符种类加一*/
}
}right++; //right移动
while(pCount==winCount){ //当移动数组字符种类个数于s1的字符种类个数相等时
if(right-left==pLen){ //当移动数组的长度跟s1长度相同时
return true;
}
if(pFreq[text[left]-'a']>0){ /*当移动数组left下标指向的
字符在s1出现次数大于0时*/
winFreq[text[left]-'a']--; /*那么移动数组该字符出现
的频数减一*/
if(winFreq[text[left]-'a']<pFreq[text[left]-'a']){
/*当移动数组left下标指向的字符出现
的字符的个数小于s1该字符出现的个数*/
winCount--; //移动数组该字符个数减一
}
}//这一步骤就是不断缩短移动数组的长度以保证这个连续的字符对应s1
left++;
}
}
return false;
}
}