1.1无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度
。
输入
: s = “pwwkew”
输出
: 3
解释
: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。 请注意,答案必须是子串
的长度,“pwke” 是一个子序列,不是子串。
滑动窗口
滑动窗口是一种基于双指针
的一种思想,两个指针指向的元素之间形成一个窗口。
窗口有两类,一种是固定大小的窗口
,一类是大小动态变化的窗口
。
什么情况可以用滑动窗口来解决实际问题呢?
1.一般给出的数据结构是数组或者字符串
2.求取某个子串或者子序列最长最短等最值问题
或者求某个目标值
时
3.该问题本身可以通过暴力求解
代码
依次以每个字符开始找不重复的子串,在每次循环过程中存储最大的长度
def lengthOfLongestSubSting(self,s):
if not s:
return 0
left=0 #窗口起始位置
lookup=set() #滑动窗口
n=len(s)
max_len=0 #最大的不重复子串的长度
cur_len=0 #当前窗口开始的不重复子串的长度
for i in range(n):
cur_len+=1
while s[i] in lookup:
lookup.remove(s[left])
left+=1
cur_len-=1
max_len=cur_len if cur_len>max_len else max_len
lookup.add(s[i])
return max_len
1.2找到字符串中所有字母异位词
给定两个字符串
s
s
s 和
p
p
p,找到
s
s
s 中所有
p
p
p 的 异位词的子串,返回这些子串的起始索引,不考虑答案输出的顺序。异位词指由相同字母重排列形成的字符串(包括相同的字符串)。
输入
: s = “cbaebabacd”, p = “abc”
输出
: [0,6]
解释
:起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的异位词。
ord('a')=97 #字符的ASCII码
chr(97)="a" #ASCII码对应的字符
根据题目要求,我们需要在字符串
s
s
s 寻找字符串
p
p
p 的异位词。因为字符串 p的异位词的长度=字符串 p的长度
,所以我们可以在字符串
s
s
s 中构造一个长度为与字符串
p
p
p的长度相同的滑动窗口
,并在滑动中维护窗口中每种字母的数量
;当窗口中每种字母的数量与字符串
p
p
p 中每种字母的数量相同时,则说明当前窗口为字符串
p
p
p 的异位词
代码
def findAnagrams(self,s,p):
s_len,p_len=len(s),len(p)
if s_len<p_len:
return []
res=[]
s_count=[0]*26 #26个英文字母
p_count = [0] * 26
for i in range(p_len):
s_count[ord(s[i])-97]+=1 #每种字符的数量
p_count[ord(p[i])-97]+=1
if s_count==p_count:
res.append(0) #从第一位开始就有异位词
for i in range(s_len-p_len):
s_count[ord(s[i])-97]-=1 #窗口向后移动
s_count[ord(s[i+p_len])-97]+=1 #对应的计算下一个窗口的数值
if s_count==p_count:
res.append(i+1) #从第二个元素开始的欢动窗口
return res