Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.
Strings consist of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
The order of output does not matter.
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".
找到字符串中所有字母易位词。给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。思路是滑动窗口(sliding window)。这个题也可以用之前的模板做,参见76,159,340。先遍历p,得到p中每个字母和他们对应的出现次数。再去遍历s,用start和end指针,end在前,当某个字母的出现次数被减少到0的时候,counter才能--。当counter == 0的时候,判断end - begin是否等于p的长度,若是,才能将此时begin的坐标加入结果集。
时间O(n)
空间O(1)
Java实现
1 class Solution { 2 public List<Integer> findAnagrams(String s, String p) { 3 List<Integer> res = new ArrayList<>(); 4 // corner case 5 if (s.length() < p.length()) { 6 return res; 7 } 8 9 // normal case 10 int[] map = new int[128]; 11 for (char c : p.toCharArray()) { 12 map[c]++; 13 } 14 int counter = p.length(); 15 int start = 0; 16 int end = 0; 17 while (end < s.length()) { 18 char c1 = s.charAt(end); 19 if (map[c1] > 0) { 20 counter--; 21 } 22 map[c1]--; 23 end++; 24 while (counter == 0) { 25 char c2 = s.charAt(start); 26 map[c2]++; 27 if (map[c2] > 0) { 28 counter++; 29 } 30 if (end - start == p.length()) { 31 res.add(start); 32 } 33 start++; 34 } 35 } 36 return res; 37 } 38 }
JavaScript实现
1 /** 2 * @param {string} s 3 * @param {string} p 4 * @return {number[]} 5 */ 6 var findAnagrams = function(s, p) { 7 let res = []; 8 if (p.length > s.length) { 9 return res; 10 } 11 12 let map = new Map(); 13 for (let c of p) { 14 map.set(c, (map.get(c) | 0) + 1); 15 } 16 17 let begin = 0, 18 end = 0, 19 counter = map.size; 20 while (end < s.length) { 21 let c = s.charAt(end); 22 if (map.has(c)) { 23 map.set(c, map.get(c) - 1); 24 if (map.get(c) === 0) { 25 counter--; 26 } 27 } 28 end++; 29 while (counter === 0) { 30 let d = s.charAt(begin); 31 if (map.has(d)) { 32 map.set(d, map.get(d) + 1); 33 if (map.get(d) > 0) { 34 counter++; 35 } 36 } 37 if (end - begin == p.length) { 38 res.push(begin); 39 } 40 begin++; 41 } 42 } 43 return res; 44 };