Leetcode第242题:有效的字母异位词

题目

给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。

字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。

示例:

示例一:
输入:
s: "cbaebabacd" p: "abc"

输出:
[0, 6]

解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。



示例二:
输入:
s: "abab" p: "ab"

输出:
[0, 1, 2]

解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的字母异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的字母异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词。


说明:
  • 字母异位词指字母相同,但排列不同的字符串。
  • 不考虑答案输出的顺序。

题解

本题解法与参考一致,采用滑动窗口法进行求解。

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        //采用滑动窗口法进行求解,思路与76题最小覆盖字串一样
        if(s.length() < p.length()){
            return new ArrayList<>();
        }
        int left = 0;
        int right = 0;
        Map<Character, Integer> window = new HashMap<>();
        Map<Character, Integer> need = new HashMap<>();
        int len = 0;    //记录匹配字符长度
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < p.length(); ++i){
            need.put(p.charAt(i), need.getOrDefault(p.charAt(i), 0) + 1);
        }
        while(right < s.length()){
            char c1 = s.charAt(right);
            if(need.containsKey(c1)){
                window.put(c1, window.getOrDefault(c1, 0) + 1);
                if(window.get(c1).intValue() == need.get(c1).intValue()){
                    len++;
                }
            }
            right++;
            while(len == need.size()){
                char c2 = s.charAt(left);
                if((right - left) == p.length()){
                    list.add(left);
                }
                if(need.containsKey(c2)){
                    window.put(c2, window.get(c2) - 1);
                    if(window.get(c2).intValue() < need.get(c2).intValue()){
                        len--;
                    }
                }
                left++;
            }
        }
        return list;
    }
}

参考:https://www.cnblogs.com/jianglinliu/p/12005717.html

猜你喜欢

转载自www.cnblogs.com/jianglinliu/p/12005822.html