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^5
  • s 由英文字母、数字、符号和空格组成

思路

滑动窗口 + 哈希集合:右端不断扩张,一旦 s[r] 已在窗口集合中,就从左端逐个删字符收缩,直到重复消除;每轮用窗口大小 r - l + 1 更新答案,左右指针各至多走一遍,O(n)O(n)。

也可用 dict 记录每个字符最后出现的下标,左端直接跳到「上次出现位置 + 1」,省去逐步收缩。

使用滑动窗口维护一个不包含重复字符的子串。窗口左边界为 l,右边界为 r(当前遍历到的字符)。

算法步骤

  1. 使用集合 a 存储当前窗口中的字符
  2. 右指针 r 不断向右扩展
  3. 如果新字符 s[r] 已存在于窗口中,则收缩左边界 l,直到窗口中不再包含该字符
  4. 更新最长子串长度 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
  • 时间复杂度:O(n)O(n),其中 nn 是字符串长度。左右指针各至多遍历一次。
  • 空间复杂度:O(|Σ|)O(|\Sigma|),其中 |Σ||\Sigma| 是字符集大小。最坏情况下窗口包含所有不同字符,但字符集有限(英文字母、数字、符号和空格),也可视为 O(min⁡(n,|Σ|))O(\min(n, |\Sigma|))。

3. 无重复字符的最长子串
https://mingsm17518.github.io/2026/09/25/刷题笔记/Hot100/滑动窗口/3. 无重复字符的最长子串/
作者
Ming
发布于
2026年9月25日
更新于
2026年10月25日
许可协议