给定两个字符串
s和p,找到s****中所有p****的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
示例 1:
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例 2:
输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
提示:
- 1 <= s.length, p.length <= 3 * 104
s和p仅包含小写字母
知识点 滑动窗口 + hash表
代码
def findAnagrams(s, p):
ls = len(s)
lp = len(p)
if lp > ls:
return []
# 0. 滑动窗口 + hash表
tp = [0 for _ in range(26)] # 存放26个字母的计数
ts = [0 for _ in range(26)]
ans = []
# - 先统计到p这么长
for i in range(lp):
tp[ord(p[i]) - ord('a')] += 1
ts[ord(s[i]) - ord('a')] += 1
if tp == ts :
ans.append(0) # 初始段
# - 再从p长度的地方往后滑
for i in range(lp , ls):
ts[ord(s[i - lp]) - ord('a')] -= 1 #头出尾进
ts[ord(s[i]) - ord('a')] += 1
if ts == tp:
ans.append(i - lp + 1)
return ans
'''
# 1. 暴力算法
ans = []
tp = sorted(p)
for i in range(ls - lp + 1):
ts = sorted(s[i:i + lp])
if tp[0] == ts[0]:
if tp == ts:
ans.append(i)
return ans
'''
'''
# 2. 滑动窗口 + hash表,这种和暴力算法一样慢
ans = []
i = 0
j = 0
dp = collections.defaultdict(int)
ds = collections.defaultdict(int)
while j < ls:
ds[s[j]] += 1
while ds[s[j]] > dp[s[j]]:
ds[s[i]] -= 1
i += 1
ans.append(i)
return ans
'''