Given two strings s
and p
, return an array of all the start indices of p
's anagrams in s
. You may return the answer in any order.
An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
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".
Constraints:
1 <= s.length, p.length <= 3 * 104
s
andp
consist of lowercase English letters.
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
counter = Counter(p)
ans = []
left = right = 0
t = Counter()
while right < len(s):
t[s[right]] += 1
while t[s[right]] > counter[s[right]]:
t[s[left]] -= 1
left += 1
if right - left + 1 == len(p):
ans.append(left)
right += 1
return ans
class Solution {
public List<Integer> findAnagrams(String s, String p) {
int[] counter = new int[26];
for (char c : p.toCharArray()) {
++counter[c - 'a'];
}
List<Integer> ans = new ArrayList<>();
int left = 0, right = 0;
int[] t = new int[26];
while (right < s.length()) {
int i = s.charAt(right) - 'a';
++t[i];
while (t[i] > counter[i]) {
--t[s.charAt(left) - 'a'];
++left;
}
if (right - left + 1 == p.length()) {
ans.add(left);
}
++right;
}
return ans;
}
}
function findAnagrams(s: string, p: string): number[] {
let n = s.length,
m = p.length;
let cnt = new Array(26).fill(0);
let ans = [];
for (let i = 0; i < m; i++) {
cnt[p.charCodeAt(i) - 97]--;
cnt[s.charCodeAt(i) - 97]++;
}
if (cnt.every(v => v == 0)) {
ans.push(0);
}
for (let i = m; i < n; i++) {
cnt[s.charCodeAt(i) - 97]++;
cnt[s.charCodeAt(i - m) - 97]--;
if (cnt.every(v => v == 0)) {
ans.push(i - m + 1);
}
}
return ans;
}
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> counter(26);
for (char c : p) ++counter[c - 'a'];
vector<int> ans;
int left = 0, right = 0;
vector<int> t(26);
while (right < s.size()) {
int i = s[right] - 'a';
++t[i];
while (t[i] > counter[i]) {
--t[s[left] - 'a'];
++left;
}
if (right - left + 1 == p.size()) ans.push_back(left);
++right;
}
return ans;
}
};
func findAnagrams(s string, p string) []int {
counter := make([]int, 26)
for _, c := range p {
counter[c-'a']++
}
var ans []int
left, right := 0, 0
t := make([]int, 26)
for right < len(s) {
i := s[right] - 'a'
t[i]++
for t[i] > counter[i] {
t[s[left]-'a']--
left++
}
if right-left+1 == len(p) {
ans = append(ans, left)
}
right++
}
return ans
}
impl Solution {
pub fn find_anagrams(s: String, p: String) -> Vec<i32> {
let (s, p) = (s.as_bytes(), p.as_bytes());
let (m, n) = (s.len(), p.len());
let mut res = vec![];
if n > m {
return res;
}
let mut counter = [0; 26];
for i in 0..n {
counter[(p[i] - b'a') as usize] += 1;
counter[(s[i] - b'a') as usize] -= 1;
}
for i in n..m {
if counter.iter().all(|&v| v == 0) {
res.push((i - n) as i32);
}
counter[(s[i] - b'a') as usize] -= 1;
counter[(s[i - n] - b'a') as usize] += 1;
}
if counter.iter().all(|&v| v == 0) {
res.push((m - n) as i32);
}
res
}
}