438.找到字符串中所有字母异位词
给定两个字符串
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" 的异位词。
思路:
找字母异位词,我们知道字母异位词有两个特点:
- 字母异位词的每个词组的异位词经过ASCLL码排序后一定是一样的词组
- 字母异位词的每个字母出现的次数是一样的
第一个特性在这道题不适用,因为结果要返回字母异位词子串的起始索引,那么只能从第二个特性出发。
根据题目要求,我们需要在字符串s寻找字符串p的异位词。因为字符串s的异位词的长度一定与字符串p的长度相同,所以我们可以在字符串s中构造一个长度为与字符串p的长度相同的滑动窗口,并在滑动中维护窗口中每种字母的数量;当窗口中每种字母的数量与字符串p中每种字母的数量相同时,则说明当前窗口为字符串的异位词。
这道题是一个大小不变的滑动窗口,也就是说左指针和右指针是同时移动的,然后每次移动都要记录窗口内字母的出现次数,通过比较数组的内容(相同字母的出现次数)是否相同来决定是不是字母异位词
Arrays.equals方法可以比较两个数组的内容是否相同
class Solution {public List<Integer> findAnagrams(String s, String p) {int sLen = s.length(), pLen = p.length();if (sLen < pLen) {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 < pLen; ++i) {++sCount[s.charAt(i) - 'a'];++pCount[p.charAt(i) - 'a'];}if (Arrays.equals(sCount, pCount)) {ans.add(0);}for (int i = 0; i < sLen - pLen; ++i) {--sCount[s.charAt(i) - 'a'];++sCount[s.charAt(i + pLen) - 'a'];if (Arrays.equals(sCount, pCount)) {ans.add(i + 1);}}return ans;}
}

