返回

Leetcode 3:无重复字符的最长子串 - 突破极限,探索高效解法

后端

破解无重复字符最长子串:滑动窗口算法的精彩之旅

在编程世界中,我们经常会遇到需要处理字符串的问题。其中一个经典问题就是「无重复字符的最长子串」,它要求找出字符串中不包含重复字符的最长连续子串。乍一看,这个问题可能有些棘手,但别担心!我们有一个强大的算法可以轻松解决它,那就是「滑动窗口」算法。

滑动窗口算法:巧妙地寻找无重复子串

想象一下你在用放大镜检查一个句子,一次只看几个单词。随着放大镜的移动,你不断地检查单词是否重复。这就是滑动窗口算法的工作原理。

  1. 设定窗口: 我们从字符串的开头开始,创建一个窗口,初始大小为 1。
  2. 滑动窗口: 我们向右移动窗口的右边界,检查窗口内是否有重复字符。
  3. 更新长度: 如果没有重复字符,我们就更新当前窗口的长度。
  4. 移动左边界: 如果遇到重复字符,我们就将窗口的左边界移动到重复字符的下一个位置。
  5. 继续滑动: 我们重复步骤 2-4,直到窗口到达字符串的结尾。

代码示例:把理论付诸实践

现在,让我们用 Python 代码来实现滑动窗口算法。

def length_of_longest_substring(s):
    max_length = 0
    start = 0
    char_index = {}  # 存储字符及其最近出现的位置

    for end, char in enumerate(s):
        if char in char_index and char_index[char] >= start:
            start = char_index[char] + 1
        char_index[char] = end
        max_length = max(max_length, end - start + 1)

    return max_length

具体解析:

  • max_length 变量保存无重复子串的最大长度。
  • start 变量标记窗口的左边界。
  • char_index 字典记录每个字符最近出现的位置。
  • 我们遍历字符串,逐个移动窗口的右边界 end
  • 如果遇到重复字符,我们就更新 start 为重复字符的下一个位置。
  • 我们不断更新 max_length 为窗口的最大长度。
  • 最终返回 max_length,即无重复字符的最长子串的长度。

实例详解:

以字符串 "abcabcbb" 为例:

  • 滑动窗口:
    • 初始窗口为 "a"。
    • 窗口向右移动,变为 "ab"。
    • 窗口继续移动,变为 "abc"。
    • 遇到重复字符 'a',左边界移动到 'b'。
    • 窗口再次移动,变为 "bc"。
    • 窗口又遇到重复字符 'c',左边界移动到 'b'。
  • 最终结果: 无重复字符的最长子串为 "abc",长度为 3。

总结:

通过滑动窗口算法,我们可以高效地找到字符串中不含重复字符的最长子串。它易于理解,在字符串处理问题中有着广泛的应用。

常见问题解答

  1. 为什么滑动窗口算法的时间复杂度为 O(n)?
    • 该算法遍历字符串一次,时间复杂度与字符串长度成正比。
  2. 滑动窗口算法如何处理 Unicode 字符?
    • 算法可以处理 Unicode 字符,但需要使用合适的哈希函数。
  3. 滑动窗口算法是否能找到所有无重复字符的子串?
    • 该算法只能找到最长的无重复字符子串。
  4. 是否存在优化滑动窗口算法的方法?
    • 可以使用哈希表来优化字符查找,但时间复杂度仍为 O(n)。
  5. 滑动窗口算法还有什么应用?
    • 该算法可用于解决其他字符串问题,如最长回文子串和无重复字母的最长单词。