「优选算法刷题」:找到字符串中所有字母异位词

发布时间:2024年01月19日

一、题目

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

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

示例?1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

?示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

二、思路解析

这道题的关键在于,想到利用一个 变量?count 来记录窗口中的 「有效字符」 个数。

而有效数字存在的前提,就是 s?中每一个字符的出现次数,一定不能超过 p 中对应符的出现次数,否则就不是题目要求的子串了。

这道题我用了 2 个数组,来记录 s 和 p 中每个字符的出现次数,其中数组下标为字符的 ACII 码值

剩下的就是滑动窗口的实现跟维护、 count 的维护,以及结果的更新了,具体步骤我也有在下面代码注释中写到啦。

三、完整代码

class Solution {
    public List<Integer> findAnagrams(String ss, String pp) {

        
        char[] s = ss.toCharArray();
        char[] p = pp.toCharArray();
        int n = s.length;
        int m = p.length;
        List<Integer> ret = new ArrayList<Integer>();

        //记录 p 中每个字符的出现次数,其中数组下标为字符的 ACII 码值
        int[] hash1 = new int [26];
        for(char ch : p){
            hash1[ch - 'a']++;
        }

        //滑动窗口
        int[] hash2 = new int [26];
        for(int left = 0 , right = 0 , count = 0; right < n ; right ++){
            char in = s[right];

            //count 用于记录有效字符「即 s 字符串中的 a 字符数量 <= p 字符串中的 a 字符数量」
            if(++hash2[in - 'a'] <= hash1[in - 'a']){
                count ++;
            }
            //进入窗口 + 维护 count

            if(right - left + 1 > m){
                char out = s[left++];
                if(hash2[out - 'a']-- <= hash1[out - 'a'] ){
                    count --;
                }
            }
            //出窗口 + 维护 count

            //更新结果
            if(count == m){
                ret.add(left);
            }
        }
        return ret;
    }
}

以上就是本篇博客的全部内容啦,如有不足之处,还请各位指出,期待能和各位一起进步!

文章来源:https://blog.csdn.net/C_Small_Cai/article/details/135694835
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。