438. 找到字符串中所有字母异位词 (滑动窗口)

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

异位词:指由相同字母重排列形成的字符串(包括相同的字符串)

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        if(p.length()>s.length()) return new ArrayList<Integer>(); // 不可能有异构串

        List<Integer> res = new ArrayList<Integer>();
        // 构建滑动窗口
        int[] pCount = new int[26]; // 统计p中每个字符出现的次数
        int[] sCount = new int[26]; // s的滑动窗口,当窗口中的统计值sCount与p的统计值pCount完全一致的时候则认为是异构字串
       
       int pLen = p.length(), sLen = s.length();
       // 初始化滑动窗口和p的统计值
        for(int i=0; i<pLen; i++) {
            pCount[p.charAt(i)-'a']++;
            sCount[s.charAt(i)-'a']++;
        }
        // 开始滑动窗口
        for(int start = 0; start<=sLen-pLen; start++){ // start<s.length()-p.length() 注意滑动窗口起始位置边界
            // 判断当前窗口中的统计值是否与pCount一致
            if(Arrays.equals(pCount,sCount)) res.add(start);
            //窗口滑动 更改窗口左边界和右边界。 同时注意最后一个窗口时,不需要在向前滑动了,既不用更新窗口边界
            if(start<sLen-pLen){
                sCount[s.charAt(start)-'a']--; // 左边界字符出现次数减一
                sCount[s.charAt(start+pLen)-'a']++; // 右边界出现字符次数加一
            }
        }
        return res;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值