给定一个字符串 s,请你找出其中不含有重复字符的最长子串的长度。
输入: s = "abcabcbb"
输出: 3
解释: 最长不重复子串是 "abc",长度为 3。这是一道非常典型的滑动窗口问题。
如果我们使用暴力解法去尝试所有子串,时间复杂度会高达 O(n²)。 我们可以通过维护一个“不含重复字符的子串窗口”来动态处理:
left 和 right 表示当前窗口的左右边界。set() 来记录窗口内已经出现的字符。class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
char_set = set()
left = 0
max_len = 0
for right in range(len(s)):
while s[right] in char_set:
char_set.remove(s[left])
left += 1
char_set.add(s[right])
max_len = max(max_len, right - left + 1)
return max_lenclass Solution:定义一个类,这在 LeetCode 是默认要求的格式,系统会自动调用类中的方法。
def lengthOfLongestSubstring(self, s: str) -> int:函数签名,表示接受一个字符串类型的参数 s,返回一个整数类型。
其中:
s: str 是类型注解,说明参数是字符串-> int 是返回类型注解,表示返回整数char_set = set()创建一个空的集合,用于记录当前窗口中的字符。
while s[right] in char_set:说明当前字符已经在窗口中了 → 出现重复 我们就不断从左边移除字符,直到窗口合法为止。
left += 1left = left + 1 的简写,表示左指针向右移动一格(窗口缩小)
"""a" → "ab" → "abc",窗口合法。"a",重复!此时不断移动左指针直到重复字符移出。3。你可以理解为“窗口在滑动”,但窗口内始终保持“无重复”的条件。
项目 | 分析 |
|---|---|
时间复杂度 | O(n),每个字符最多进入和移除一次 |
空间复杂度 | O(min(n, m)),m 为字符集大小,如 ASCII 为 128 |
self 是什么?self,代表“这个对象自身”。set() 而不是 list?set 查找是否包含某元素的效率是 O(1),list 是 O(n)class 可以吗?def length_of_longest_substring(s: str) -> int:
char_set = set()
left = 0
max_len = 0
for right in range(len(s)):
while s[right] in char_set:
char_set.remove(s[left])
left += 1
char_set.add(s[right])
max_len = max(max_len, right - left + 1)
return max_len技术点 | 说明 |
|---|---|
滑动窗口 | 用两个指针控制当前区间 |
集合 set() | 用于存储并快速查找重复字符 |
双指针 | 控制窗口动态扩展与收缩 |
类型注解 | 增强代码可读性,利于调试 |
这道题是滑动窗口入门题,非常适合用来掌握双指针、集合操作、条件判断等核心编程思想。
🎯 掌握它后,你可以挑战更多类似问题,如: