时间:2021-02-25
题目地址:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/
题目难度:Medium
题目描述:
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。
示例 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:滑动窗口
labuladong算法框架的python版本放这里了,熟记于心啊
def slidingWindow( s: str, t: str) -> str:
need, window = {}, {}
for i in t:
need[i] = need.setdefault(i, 0) + 1
left, right = 0, 0
valid = 0
while right < len(s):
# a 是将要滑入窗口的字符
a = s[right]
# 右移窗口
right += 1
# 进行窗口内数据的更新操作 【思考点】
...
# debug代码
print(f'window:[{left}, {right}]')
# 判断左侧窗口是否要收缩
while 收缩的条件:【思考点】
# b 是将要移出窗口的字符
b = s[left]
# 左移窗口
left += 1
# 进行窗口内数据的更新操作【思考点】
...
【思考点】结果应在扩大窗口还是缩小窗口更新
代码段1:通过
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
need, window = {}, {}
for i in p:
need[i] = need.setdefault(i, 0) + 1
left, right = 0, 0
valid = 0
res = []
while right < len(s):
a = s[right]
right += 1
if a in need:
window[a] = window.setdefault(a, 0) + 1
if window[a] == need[a]:
valid += 1
while right - left == len(p):
if valid == len(need):
res.append(left)
b = s[left]
left += 1
if b in need:
if window[b] == need[b]:
valid -= 1
window[b] -= 1
return res
总结:
- 这其实和排列是一个套路。默写框架,想清楚四个思考点就行