力扣438(Java)-找到字符串中所有字母异位词(中等)
题目:
给定两个字符串 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" 的异位词。
提示:
- 1 <= s.length, p.length <= 3 * 104
- s 和 p 仅包含小写字母
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
滑动窗口+哈希表(数组)
- 因为给定的字符串都是由小写字母组成,故可以使用数组形式的哈希表先统计出字符串p中各字符出现的次数;
- 维护一个窗口,窗口的长度始终与p的长度一致,定义两个指针left代表窗口的起始位置,right代表窗口的结束位置;
- 判断窗口中的字符数量和 p 中出现的字符数量是否一致,如果一致就添加窗口的起始位置到结果中,否则,就移动窗口位置,将结束位置右移,起始位置也右移并删除掉起始位置对应字符的数量。
代码:
1 class Solution { 2 public List<Integer> findAnagrams(String s, String p) { 3 int m = s.length(), n = p.length(); 4 //定义一个数组统计p中字符出现的次数 5 int[] count = new int[26]; 6 for(int i = 0; i < p.length(); i++){ 7 count[p.charAt(i) - 'a']++; 8 } 9 //定义双指针为窗口的起始和结束位置 10 int left = 0, right = 0; 11 int[] window = new int[26]; 12 //定义一个字符串用于返回结果 13 List<Integer> ans = new ArrayList<>(); 14 while (right < m){ 15 window[s.charAt(right) - 'a']++; 16 //控制窗口大小等于p的长度 17 if (right - left + 1 == n){ 18 if (Arrays.equals(window, count)){ 19 ans.add(left); 20 } 21 //将窗口左指针对应的字符数量减减 22 window[s.charAt(left) - 'a']--; 23 //左指针向右移动 24 left++; 25 } 26 right++; 27 } 28 return ans; 29 } 30 }