LC438 找到字符串中所有字母异位词

203 阅读1分钟

题目

Given two strings s and p, return an array of all the start indices of p 's anagrams in s. You may return the answer in any order. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

给两个string sp, 返回s中包含p所有字符的子串起点下标  

Example 1:

Input: s = "cbaebabacd", p = "abc"
Output: [0,6]
Explanation:
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".

Example 2:

Input: s = "abab", p = "ab"
Output: [0,1,2]
Explanation:
The substring with start index = 0 is "ab", which is an anagram of "ab".
The substring with start index = 1 is "ba", which is an anagram of "ab".
The substring with start index = 2 is "ab", which is an anagram of "ab".

 

Constraints:

  • 1 <= s.length, p.length <= 3 * 10^4
  • s and p consist of lowercase English letters.

思路

  • 典型的滑动窗口,直接开套
  • 不考虑顺序,有重复值,p的字符用pMap维护
  • 循环s的所有字符,放入另一个sMap,使用滑动窗口保证sMap的size始终和pMap一样,
  • 这种情况下判断两个Map内元素及数量是否一致

代码

    public List<Integer> findAnagrams(String s, String p) {
        //快速判断特殊情况
        if (p.length() > s.length()) {
            return Collections.emptyList();
        }
        List<Integer> result = new ArrayList<>();
        //定义两个map分别存储s和p的字符
        Map<Character, Integer> pCharMap = new HashMap<>();
        Map<Character, Integer> sCharMap = new HashMap<>();
        
        //初始化p的Map
        for(char c : p.toCharArray()) {
            pCharMap.merge(c, 1, Integer::sum);
        }
        for(int i = 0; i < s.length(); i++) {
            sCharMap.merge(s.charAt(i), 1, Integer::sum);
            //当滑动窗口=p的大小时开始滑动
            if (i >= p.length()) {
                //剔除最左侧的字符
                char left = s.charAt(i - p.length());
                if (sCharMap.get(left) == 1) {
                    sCharMap.remove(left);
                } else {
                    sCharMap.put(left, sCharMap.get(left) - 1);
                }
            }
            //如果此时两个Map元素一样,存入起点下标
            if (pCharMap.equals(sCharMap)) {
                result.add(i - p.length() + 1);
            }
        }
        return result;
    }