3. 无重复字符的最长子串
题目
3. 无重复字符的最长子串(中等)
给定一个字符串 s ,请你找出其中不含有重复字符的
最长 子串 的长度。
示例 1:
输入:
abcabcbb输出:
3解释:因为无重复字符的最长子串是
"abc",所以其长度为 3。注意 “bca” 和 “cab”
也是正确答案。
示例 2:
输入:
bbbbb输出:
1解释:因为无重复字符的最长子串是
"b",所以其长度为 1。
示例 3:
输入:
pwwkew输出:
3解释:因为无重复字符的最长子串是
"wke",所以其长度为 3。请注意,你的答案必须是
子串 的长度,"pwke"
是一个子序列,不是子串。
提示:
0 <= s.length <= 10^5s由英文字母、数字、符号和空格组成
思路
滑动窗口 + 哈希集合:右端不断扩张,一旦 s[r]
已在窗口集合中,就从左端逐个删字符收缩,直到重复消除;每轮用窗口大小
r - l + 1
更新答案,左右指针各至多走一遍,。
也可用
dict记录每个字符最后出现的下标,左端直接跳到「上次出现位置 + 1」,省去逐步收缩。
使用滑动窗口维护一个不包含重复字符的子串。窗口左边界为 l,右边界为 r(当前遍历到的字符)。
算法步骤
- 使用集合
a存储当前窗口中的字符 - 右指针 r 不断向右扩展
- 如果新字符 s[r] 已存在于窗口中,则收缩左边界 l,直到窗口中不再包含该字符
- 更新最长子串长度 ans
代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
ans = 0
pre = set()
l = 0
for r in range(len(s)):
while s[r] in pre:
pre.remove(s[l])
l += 1
ans = max(ans, r - l + 1)
pre.add(s[r])
return ans- 时间复杂度:,其中 是字符串长度。左右指针各至多遍历一次。
- 空间复杂度:,其中 是字符集大小。最坏情况下窗口包含所有不同字符,但字符集有限(英文字母、数字、符号和空格),也可视为 。