438. Find All Anagrams in a String
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.
Strings consists 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".
Approach #1: C++. Using sort and substr[Time Limit Exceeded]
class Solution { public: vector<int> findAnagrams(string s, string p) { vector<int> ans; if (s.length() < p.length()) return ans; sort(p.begin(), p.end()); int len = p.size(); for (int i = 0; i < s.length()-len+1; ++i) { string temp = s.substr(i, len); sort(temp.begin(), temp.end()); if (temp == p) ans.push_back(i); } return ans; } };
Approach #2: C++. Using sliding windows.
class Solution { public: vector<int> findAnagrams(string s, string p) { unordered_map<char, int> mp; vector<int> ans; for (int i = 0; i < p.length(); ++i) { mp[p[i]]++; } int begin = 0, end = 0; int counter = mp.size(); while (end < s.length()) { char tempc = s[end]; if (mp.count(tempc)) { mp[tempc]--; if (mp[tempc] == 0) counter--; } end++; while (counter == 0) { char tempc = s[begin]; if (mp.count(tempc)) { mp[tempc]++; if (mp[tempc] > 0) counter++; } if (end - begin == p.length()) { ans.push_back(begin); } begin++; } } return ans; } };
Approach #3: Java.
class Solution { public List<Integer> findAnagrams(String s, String t) { List<Integer> result = new LinkedList<>(); if (t.length() > s.length()) return result; Map<Character, Integer> map = new HashMap<>(); for (char c : t.toCharArray()) { map.put(c, map.getOrDefault(c, 0) + 1); } int counter = map.size(); int begin = 0, end = 0; int head = 0; int len = Integer.MAX_VALUE; while (end < s.length()) { char c = s.charAt(end); if (map.containsKey(c)) { map.put(c, map.get(c) - 1); if (map.get(c) == 0) counter--; } end++; while (counter == 0) { char tempc = s.charAt(begin); if (map.containsKey(tempc)) { map.put(tempc, map.get(tempc) + 1); if (map.get(tempc) > 0) { counter++; } } if (end-begin == t.length()) { result.add(begin); } begin++; } } return result; } }
Approach #4: Python.
from collections import Counter class Solution(object): def findAnagrams(self, s, p): """ :type s: str :type p: str :rtype: List[int] """ res = [] pCounter = Counter(p) sCounter = Counter(s[:len(p)-1]) for i in range(len(p)-1, len(s)): sCounter[s[i]] += 1 if sCounter == pCounter: res.append(i-len(p)+1) sCounter[s[i-len(p)+1]] -= 1 if sCounter[s[i-len(p)+1]] == 0: del sCounter[s[i-len(p)+1]] return res
Time Submitted | Status | Runtime | Language |
---|---|---|---|
a few seconds ago | Accepted | 240 ms | python |
43 minutes ago | Accepted | 44 ms | cpp |
an hour ago | Accepted | 61 ms | java |
永远渴望,大智若愚(stay hungry, stay foolish)