438-find-all-anagrams-in-a-string¶
Try it on leetcode
Description¶
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.
Solution(Python)¶
class Solution:
def __init__(self):
self.a = ord("a")
def findAnagrams(self, s: str, p: str) -> List[int]:
return self.windowsliding(s, p)
"""
create Counter Dict of p
for all substrings in s:
check if it's anagram if s
Time Complexty: O(n^2)
Space Complexity: O(1)
"""
def bruteforce(self, s, p):
n = len(s)
cnts = Counter(p)
res = []
for i in range(n):
for j in range(i, n):
sub_s = s[i: j + 1]
if Counter(sub_s) == cnts:
res.append(i)
return res
"""
create Frequency counter table of p (atmost 26 letters)
create Frequency counter table for current window of size m on s
slide over the s:
if two frequency table matches:
add start index to the solution
increment end of the slider
decrement the start of the slider
finally check for substring at the end of the s
Time Complexty: O(n)
Space Complexity: O(1)
"""
def windowsliding(self, s, p):
n = len(s)
m = len(p)
if m > n:
return []
res = []
countP = [0] * 26
countCW = [0] * 26
for i in range(m):
countP[ord(p[i]) - self.a] += 1
countCW[ord(s[i]) - self.a] += 1
for i in range(m, n):
if countP == countCW:
res.append(i - m)
countCW[ord(s[i]) - self.a] += 1
countCW[ord(s[i - m]) - self.a] -= 1
if countP == countCW:
res.append(n - m)
return res