小黑代码
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
# 串p长度
n_p = len(p)
# 串s长度
n_s = len(s)
# 计数字典
flags = collections.Counter(p)
# 统计字典
map_ = dict((k, 0) for k in p)
# 匹配到的字符个数
count = 0
# 头尾指针
left = right = 0
# 目标数组
results = []
# 开始迭代
while right < n_s:
# 该字符不在目标串p中,则left和right都跳到它
if s[right] not in p:
right += 1
left = right
count = 0
map_ = dict((k, 0) for k in p)
# 该字符在目标串p中
else:
# 直到该字符的个数小于p中的个数
while map_[s[right]] >= flags[s[right]]:
map_[s[left]] -= 1
count -= 1
left += 1
# 将其加入map_
map_[s[right]] += 1
count += 1
# 满足条件
if count == n_p:
results.append(left)
right += 1
return results
滑动窗口法
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
# 两个字符串长度
n_s = len(s)
n_p = len(p)
# 跳出
if n_p > n_s:
return []
# 初始化计数数组
flag_s = [0] * 26
flag_p = [0] * 26
# 结果数组
results = []
# 判断窗口初试位置是否成立
for i in range(n_p):
flag_s[ord(s[i])-97] += 1
flag_p[ord(p[i])-97] += 1
if flag_p == flag_s:
results.append(0)
# 开始滑动窗口
for i in range(n_s-n_p):
flag_s[ord(s[i+n_p])-97] += 1
flag_s[ord(s[i])-97] -= 1
# 判断是否符合条件
if flag_p == flag_s:
results.append(i+1)
return results
优化后的滑动窗口
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
# 结果数组
results = []
# 两个字符串的长度
n_s = len(s)
n_p = len(p)
# 非法情况
if n_p > n_s:
return results
# 计数数组
count = [0] * 26
# 计算初始状态
for i in range(n_p):
count[ord(s[i])-97] += 1
count[ord(p[i])-97] -= 1
# 计算差值(计算不同的字符品种个数)
diff = [t != 0 for t in count].count(True)
# 判断初始条件是否符合要求
if not diff:
results.append(0)
# 开始滑动窗口
for i in range(n_s-n_p):
# 判断s字符串中准备滑出的字符其差值
# 如果为1,则表示滑出后,该字符数量在扔掉该字符的窗口内与字符串p中的该字符数量相同,差值减1
if count[ord(s[i])-97] == 1:
diff -= 1
# 如果是0,则表示滑出后,该字符数量在扔掉该字符的窗口内与字符串p中的该字符数量相比,少1,增加了一个字符品种的差距,差值加1
elif not count[ord(s[i])-97]:
diff += 1
count[ord(s[i])-97] -= 1
# 判断s字符串中将要滑入的字符其差值
# 如果为-1,则表示滑入后,该字符数量在加入该字符的窗口内与字符串p中的该字符数量相同,差值减1
if count[ord(s[i+n_p])-97] == -1:
diff -= 1
# 如果为0,则表示滑入后,该字符数量在加入该字符的窗口内与字符串p中的该字符数量相比,多1,增加了一个字符品种的差距,差值加1
elif not count[ord(s[i+n_p])-97]:
diff += 1
count[ord(s[i+n_p])-97] += 1
# 判断是否符合要求
if not diff:
results.append(i+1)
return results
小黑改编(优化版滑动窗口)
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
# 结果数组
results = []
# 两个字符串的长度
n_s = len(s)
n_p = len(p)
# 非法情况
if n_p > n_s:
return results
# 计数数组
count = [0] * 26
# 计算初始状态
for i in range(n_p):
count[ord(s[i])-97] += 1
count[ord(p[i])-97] -= 1
# 计算差值
diff = sum([abs(t) for t in count])
# 判断初始条件是否符合要求
if not diff:
results.append(0)
# 开始滑动窗口
for i in range(n_s-n_p):
# 判断s字符串中准备滑出的字符其差值
if count[ord(s[i])-97] > 0:
diff -= 1
elif count[ord(s[i])-97] <= 0:
diff += 1
count[ord(s[i])-97] -= 1
# 判断s字符串中将要滑入的字符其差值
if count[ord(s[i+n_p])-97] < 0:
diff -= 1
elif count[ord(s[i+n_p])-97] >= 0:
diff += 1
count[ord(s[i+n_p])-97] += 1
# 判断是否符合要求
if not diff:
results.append(i+1)
return results
小黑生活
学校的蓝天,有种诗和远方的感觉
翻翻两年前的聊天记录,笑死了
晚餐烤冷面+饺子
坐车回家,享受风景,回去练琴
眼睛有些对了,继续观察
将这本书的最后部分读完,在最后的日子再借本新书看看
晚餐吃个麻辣烫
突然想野营了,买个帐篷,小伙伴们约起来~
带领中老黑和阿黄去挑战小怪兽,带领大家一起快乐运动,挑战自己,尽管大家平时不怎么运动,很欣慰大家都坚持下来了
回宿舍烤肠西瓜约起来
他们王者干到凌晨两点,我在刷题,可惜晚上失眠了
直接午餐牛肉面
我们仨一起骑车去按摩,中老黑体验新车去昌平十三陵
去迪卡侬体验帐篷