来源:LeetCode
难度:中等
问题详情:
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
以s = 'abcabcbb’
为例,该解法的求解过程为:
hashDict
中依次存储'a':0, 'b':1, 'c':2
s
到第二个'a'
时,检测到 hashDict
中存在'a'
,记录当前hashDict
的长度,记录最长的子串长度max_len
s
删除重复元素第一次出现的位置及之前的所有元素,举例说将删除第一个'a'
以及之前所有的元素,当然这里的a
前面没有元素hashDict
s
转换为集合形式set(s)
后的长度小于max_len
停止循环,这个判断条件十分重要,可以大幅降低时间消耗。class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
hashDcit = {}
max_len = 0
while len(set(s)) > max_len:
for i, item in enumerate(s):
if item in hashDcit:
max_len = max(max_len, len(hashDcit))
s = s[hashDcit[item]+1:]
hashDcit = {}
break
else:
hashDcit[item] = i
return max_len
该解法使用 滑动窗口+集合 实现。
head=end=0
slide_list=set()
s[end]
不在slide_list
中,则添加至集合slide_list
中,然后尾指针end
右移,并使得max_len +1
s[end]
在slide_list
中,则按照顺序从slide_list
中pop出之前添加的元素,每次pop后头指针head
右移,直至s[end]
不在slide_list
中。详细描述可以参考:简单易懂Java/C++ /Python/js/go【滑动窗口】- 无重复字符的最长子串
代码如下所示:
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
max_len = 0
end = 0
head = 0
slide_list = set()
while end < len(s):
while s[end] in slide_list:
slide_list.remove(s[head])
head += 1
else:
slide_list.add(s[end])
max_len = max(len(slide_list), max_len)
end += 1
return max_len