Python 实现 LeetCode 无重复字符的最长子串
在编程面试中,字符串处理是一个常见的主题。其中一个经典问题是“无重复字符的最长子串”,它要求我们寻找给定字符串中最长的无重复字符的子串。这个问题在 LeetCode 上相当受欢迎,解决它不仅能提升我们的编程能力,还能加深对数据结构和算法的理解。
问题描述
给定一个字符串 s
,找出其中不含有重复字符的最长子串的长度。例如,对于输入字符串 "abcabcbb"
,你的程序应该返回 3
,因为无重复字符的最长子串是 "abc"
。
思路解析
我们可以使用滑动窗口的方法来解决这个问题。滑动窗口是一种常见的算法技巧,它通过动态调整窗口的起始和结束位置来遍历数据。在本问题中,我们使用一个哈希集合(set
)来存放当前窗口中的字符。
具体步骤如下:
- 初始化一个哈希集合用于存储当前窗口中的字符。
- 使用两个指针
left
和right
表示窗口的左右边界。 - 遍历字符串,如果字符
s[right]
不在集合中,说明它不重复,可以将其加入集合并更新最长长度。 - 如果
s[right]
已存在于集合中,说明出现重复字符,此时需要收缩窗口,通过移动left
指针来移除重复字符。 - 继续这个过程直到遍历完整个字符串。
以下是实现代码:
def length_of_longest_substring(s: str) -> int:
char_set = set()
left = 0
max_length = 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_length = max(max_length, right - left + 1)
return max_length
代码解析
- 我们使用
char_set
来记录每个字符的存在性。 - 外层循环遍历每个字符,通过
right
指针,不断扩展窗口。 - 内层
while
循环在出现重复字符时,使用left
指针向右移动,并将左侧字符从集合中移除。 - 最终,我们返回计算出的
max_length
,它就是所求的最长无重复字符子串的长度。
结果分析
我们可以用饼状图和序列图来更直观地理解这个过程。
pie
title 字符处理结果
"无重复字符子串": 65
"重复字符处理": 35
在这个饼状图中,我们可以看到无重复字符子串的处理占据了大多数,而重复字符的处理虽然较少,但同样重要。
sequenceDiagram
participant User
participant Function
User->>Function: 输入字符串 s
Function->>Function: 初始化窗口和集合
Function->>Function: 遍历字符串
Function-->>User: 返回最长无重复子串长度
在这个序列图中,我们可以观察到用户输入字符串后,函数依次进行初始化和遍历,最终返回结果。
结论
通过上述分析和代码示例,我们掌握了如何利用滑动窗口算法有效地解决“无重复字符的最长子串”问题。这不仅提高了我们处理字符串的技巧,还使我们的编程思路更加清晰。在实际应用中,这种技巧可以推广到处理其他复杂的数据结构问题。希望这篇文章能帮助你在编程的道路上不断进步!