Python 实现 LeetCode 无重复字符的最长子串

在编程面试中,字符串处理是一个常见的主题。其中一个经典问题是“无重复字符的最长子串”,它要求我们寻找给定字符串中最长的无重复字符的子串。这个问题在 LeetCode 上相当受欢迎,解决它不仅能提升我们的编程能力,还能加深对数据结构和算法的理解。

问题描述

给定一个字符串 s,找出其中不含有重复字符的最长子串的长度。例如,对于输入字符串 "abcabcbb",你的程序应该返回 3,因为无重复字符的最长子串是 "abc"

思路解析

我们可以使用滑动窗口的方法来解决这个问题。滑动窗口是一种常见的算法技巧,它通过动态调整窗口的起始和结束位置来遍历数据。在本问题中,我们使用一个哈希集合(set)来存放当前窗口中的字符。

具体步骤如下:

  1. 初始化一个哈希集合用于存储当前窗口中的字符。
  2. 使用两个指针 leftright 表示窗口的左右边界。
  3. 遍历字符串,如果字符 s[right] 不在集合中,说明它不重复,可以将其加入集合并更新最长长度。
  4. 如果 s[right] 已存在于集合中,说明出现重复字符,此时需要收缩窗口,通过移动 left 指针来移除重复字符。
  5. 继续这个过程直到遍历完整个字符串。

以下是实现代码:

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: 返回最长无重复子串长度

在这个序列图中,我们可以观察到用户输入字符串后,函数依次进行初始化和遍历,最终返回结果。

结论

通过上述分析和代码示例,我们掌握了如何利用滑动窗口算法有效地解决“无重复字符的最长子串”问题。这不仅提高了我们处理字符串的技巧,还使我们的编程思路更加清晰。在实际应用中,这种技巧可以推广到处理其他复杂的数据结构问题。希望这篇文章能帮助你在编程的道路上不断进步!