📅  最后修改于: 2023-12-03 15:40:00.668000             🧑  作者: Mango
给定一个由小写字母组成的字符串 s
和一个非空字符串 p
,搜索 s
中所有是 p
的排列的子串,返回这些子串的起始索引。字符串只包含小写英文字母,并且字符串 s
和 p
的长度都不超过 20,100。
排列指字母的相对位置可以改变。例如,字符串 abc
的排列是 abc
、acb
、bac
、bca
、cab
和 cba
。
这是一个经典问题,可以使用队列来解决。首先,我们将字符串 p
中的字符以及它们出现的次数记录下来,然后用队列来维护一个长度为 p
的滑动窗口,在每个位置上,我们将字符加入队列中,并检查队列是否匹配 p
中的字符及其出现次数。如果队列匹配,我们就把当前位置加入结果数组中。
具体地,我们使用两个哈希表 need
和 window
来维护滑动窗口中字符出现的次数。其中,need
记录 p
中每个字符出现的次数,window
记录当前滑动窗口中每个字符出现的次数。我们还需要一个变量 valid
来表示当前滑动窗口中已经匹配 p
中字符的个数。在移动滑动窗口时,我们需要更新窗口中字符出现的次数以及更新 valid
的值,如果当前队列满足条件,则将左端点加入结果数组中。
def findAnagrams(s: str, p: str) -> List[int]:
n = len(s)
m = len(p)
if n < m:
return []
ans = []
need = {}
window = {}
for c in p:
if c not in need:
need[c] = 0
need[c] += 1
left = 0
right = 0
valid = 0
while right < n:
c = s[right]
right += 1
if c in need:
if c not in window:
window[c] = 0
window[c] += 1
if window[c] == need[c]:
valid += 1
while right - left >= m:
if valid == len(need):
ans.append(left)
d = s[left]
left += 1
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1
return ans
队列是一种非常有用的数据结构,在解决一些滑动窗口问题时,特别有效。在这个问题中,我们学习了如何使用队列来判断字符串 s
中是否存在由字符串 p
的字符排列组成的子串,并且还学习了如何使用哈希表来维护字符出现的次数。这是一个非常好的问题,值得深入掌握。