给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
滑动窗口基本思想:
首先,滑动窗口是具有:左边界 和 右边界 的
- step1:左边界、右边界均位于字符串的最左端
- step2:右边界不断向右移动,直到子串中出现重复的字符为止
- step3:出现重复的字符后,左边界不断向右移动,直到子串中无重复的字符为止
- step4:重复 step2、step3 直到字符串遍历结束
class Solution:
def lengthOfLongestSubstring(self, s):
from collections import defaultdict
# 容器,利用默认字典的 key 值去重特性,保证存储的字符串无重复
lookup = defaultdict(int)
# 左边界
start = 0
# 右边界
end = 0
# 返回值(无重复子串的长度)
max_len = 0
# 信号,当重复字符出现时flag = 1;否则 flag = 0
flag = 0
while end < len(s):
# 1. 重复字符检测器:重复字符出现 flag “亮起” --> flag = 1
if lookup[s[end]] > 0:
flag += 1
# 2. 在保证窗口内的 value 值均大于等于 1 前提下,右边界不断向右移动
lookup[s[end]] += 1
end += 1
# 3. flag > 0,说明出现重复的字符串
while flag > 0:
# 3.1 容器中重复的字符(key)对应的 value 值是大于1的
if lookup[s[start]] > 1:
# 将标记复原
flag -= 1
# 3.2 右边界不断右移,并将 value 值复原(窗口外的 key 对应的 value 值均为 0)
lookup[s[start]] -= 1
start += 1
max_len = max(max_len, end - start)
return max_len