找到字符串中所有字母异位词 滑动窗口
给定两个字符串 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" 的异位词。
思路:
使用滑动窗口。因为这道题当中对异位词的判断正好可以用滑动窗口当中的字典来做,不需要我们考虑字符串的顺序。滑动窗口之前有写过一两个题目了,几乎可以用一种固定的模板写出来,只不过我们要根据题意进行一些适当的修改。
我们同样定义两个字典has和need,need就是我们的最终目标,has则是窗口当前包含的元素。
我们的窗口从左边开始移动,逐渐扩大并接收字符串中的元素,窗口收缩的条件是当窗口的大小等于字符串p即目标字符串长度,因为这种情况下再拉长窗口也没有意义了。其他很多细节和之前写过的滑动窗口几乎一致了,直接看代码吧,我几乎每一行都写了注释:
代码:
class Solution(object):
def findAnagrams(self, s, t):
def tianjia(d,c):#将元素c添加到字典d的函数,后面要经常用,就先定义出来
if c in d:
d[c]+=1
else:
d[c]=1
#定义窗口的左右边界,与has,need字典
left=0
right = 0
has={}#has表示窗口当前包含的元素与个数
need = {}#need表示我们的目标元素与个数
lenth=len(s)
if lenth<len(t):#如果给的第一个字符串长度小于第二个字符串长度,属于非法输入
return []#返回空
valid=0#valid表示当前满足条件的字符个数,如果valid=t的长度,则找到异位词
res = []
for i in t:#先把t字符串全部添加到need里
tianjia(need,i)
while(right<lenth):#开始滑动窗口,第一层while写右指针
c = s[right]#右指针扩大的同时检查新加入到元素c
right+=1
if c in need:#如果c是我们所需
tianjia(has,c)#假如字典has
if has[c]==need[c]:#判断是否这个元素个数满足要求了
valid +=1#满足则valid+1
while(right-left>=len(t)):#第二层while写收缩条件,若窗口长度为len(t)就收缩
if valid==len(need):#收缩前检查当前是否找到了异位词
res.append(left)#如果找到了,就添加到结果列表
cc = s[left]#左指针收缩的同时检查要删除的元素cc
left+=1#左窗口收缩
if cc in need:#如果删除的这个在need里
has[cc]-=1#has字典里对应减1
if has[cc]+1==need[cc]:#如果减完后has和need差1了
valid-=1#证明刚刚还满足要求,现在不满足了,valid-1
return res
小结:
这道题就是用滑动窗口来解决的,可以把一些滑动窗口题放到一起对比一下,看起来代码很长,但基本思路都是这样的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了