LeetCode 438.找到字符串中所有字母异位词

1、题目描述

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

2、算法思路

        异位词的长度是和p的长度是固定的。是连续的窗口,所以使用滑动窗口来解决,但是是固定大小的窗口。

        并且使用count来记录窗口中的字母的种类和个数。当count中记录的种类和个数和p的种类和个数一样就可以更新结果。

3、算法流程

        创建2个大小为26的数组,其中都是下标是0表示a,1表示b以此类推。hash1统计p中字符出现的种类和个数,hash2表示s出现的种类和个数。严格来说是用来记录窗口中的种类和个数。如果right的值比如是b,那么就寻找 hash2[right - 'a'] <= hash1[right - 'a'] 如果条件完成,就会表示目前是有效字符,count++。

比如 s   aabc  left = 0,right = 1

        p    abc

count = 1,因为p中的a只出现一次,所以有效字母值a也只能出现一次,才是有效字符,当right=0是count++了。

最后当count==p.length();//更新结果

4、算法代码

class Solution {
   public List<Integer> findAnagrams(String s, String p) {
        List<Integer> ret = new ArrayList<>();
        char[] ss = s.toCharArray();
        char[] pp = p.toCharArray();

        int[] hash1 = new int[26];//统计p中的字符出现的个数
        for (char ch : pp)hash1[ch - 'a']++;

        int[] hash2 = new int[26];//统计s中字符出现的个数
        int n = p.length(),m = s.length();//count用来统计滑动窗口中的有效字符
        for (int left = 0,right = 0,count = 0;right < m;right++){
            char into = ss[right];
            //进窗口,然后判断right的元素在滑动窗口中的个数和对应的字符是否存在于p,如果是存在并且小于就count的有效字符++
            if (++hash2[into - 'a'] <= hash1[into - 'a'])count++;//先++在比较大小
            
            //判断,窗口的大小等于p的大小
            if (right-left+1 > n){
                char out = ss[left++];//先赋值在left++
                if (hash2[out - 'a']-- <= hash1[out - 'a'])//先判断<=才可以减--,因为如果是2个连续的字符就只能算一个有效字符
                    count--;
            }
            //更新结果
            if (count == n) ret.add(left);


        }
        return ret;
    }
}

5、运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值