算法练习题08:找到字符串中所有字母异位词

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int len1 = s.length();
        int len2 = p.length();
        if(len1<len2){
            return new ArrayList<Integer>();
        }
        List<Integer> ans = new ArrayList<Integer>();
        int[] sCount = new int[26];
        int[] pCount = new int[26];
        for(int i = 0;i<len2;i++){
            sCount[s.charAt(i) - 'a']++;
            pCount[p.charAt(i) - 'a']++;
        }
        if(Arrays.equals(sCount,pCount)){
            ans.add(0);
        }
        for(int i = 0;i<len1-len2;i++){
            sCount[s.charAt(i)-'a']--;
            sCount[s.charAt(i+len2)-'a']++;
            if(Arrays.equals(sCount,pCount)){
                ans.add(i+1);
            }
        }
        return ans;
    }
}

主要步骤解释:

  1. 输入参数与边界检查:

    • len1 和 len2 分别是字符串 s 和 p 的长度。
    • 如果 s 的长度比 p 短,那么显然不可能存在字母异位词,直接返回一个空列表。
  2. 初始化计数数组:

    • sCount 和 pCount 是两个长度为 26 的数组,用来记录当前窗口内和字符串 p 的每个字母的出现频率。这里假设字母都是小写字母,因此每个字母可以通过 char - 'a' 映射到数组中的索引。
    • 首先,遍历 p 的长度,将 p 中每个字母的出现频率记录在 pCount 中,同时初始化 s 中前 pLen 个字母的频率到 sCount 中。
  3. 初始比较:

    • 如果初始化后的 sCount 和 pCount 相等,说明 s 的起始部分(长度为 len2)是一个字母异位词。此时将起始索引 0 加入答案列表 ans 中。
  4. 滑动窗口遍历字符串 s

    • 从 s 的第 len2 个字符开始,利用滑动窗口方法,依次移动窗口:
      • 移除窗口的第一个字符,即窗口左侧的字符,将它从 sCount 中对应字母的频率减一。
      • 添加新的字符(窗口右侧新加入的字符),将它的频率加一。
    • 在每次调整窗口后,检查 sCount 是否与 pCount 相等,若相等,则当前窗口中的子串是一个字母异位词,将起始索引加入 ans 中。
  5. 返回结果:

    • 最后返回 ans,其中包含了所有找到的字母异位词子串的起始索引。

核心思想:

这个算法的核心是利用“滑动窗口”的思想来比较子串是否是字母异位词。通过每次滑动窗口时更新频率计数数组,我们可以在 O(n) 的时间复杂度内解决问题,而不需要每次移动窗口都重新计算整个子串的频率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值