leetcode力扣567. 字符串的排列(详细注释)

该博客讨论了一个编程问题,即如何判断一个字符串(s2)是否包含另一个字符串(s1)的排列。解决方案是使用滑动窗口和字符频率数组来比较两个字符串的字符分布。当滑动窗口内的字符种类数与目标字符串相同,并且窗口长度等于目标字符串长度时,返回true,否则返回false。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给你两个字符串 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;
         
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值