返回

剖析 LeetCode 第 3 号问题:挖掘不重复字符的最长子串的奥秘

见解分享

引言

作为一名算法爱好者,LeetCode 绝对是你的必经之地。第 3 号问题:“无重复字符的最长子串”是一道难度为 Medium 的题目,目前通过率仅为 29.0%。这道题看似简单,却蕴含着巧妙的算法思想。

问题概述

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例

给定字符串 "abcabcbb",则最长子串为 "abc",长度为 3。
给定字符串 "bbbbbbb",则最长子串为 "b",长度为 1。
给定字符串 "pwwkew",则最长子串为 "wke",长度为 3。

算法思路

要解决这个问题,我们可以采用“滑动窗口”的算法思想。滑动窗口是一种算法技术,常用于解决字符串匹配问题。其基本思想是使用一个窗口在字符串中滑动,并不断调整窗口的大小,以寻找最符合条件的子串。

算法步骤

  1. 初始化滑动窗口。

    • 将窗口的起始位置和结束位置都设为 0。
    • 建立一个哈希表,用于记录窗口中出现的字符。
    • 初始化一个变量 max_length,用于记录最长子串的长度。
  2. 滑动窗口。

    • 将窗口的结束位置向右移动一位。
    • 如果窗口中没有重复字符,则将 max_length 更新为窗口的长度。
    • 如果窗口中存在重复字符,则将窗口的起始位置向右移动一位,并从哈希表中删除相应的字符。
  3. 重复步骤 2,直至窗口的结束位置达到字符串的末尾。

代码实现

def length_of_longest_substring(s):
    """
    :type s: str
    :rtype: int
    """
    # 初始化滑动窗口
    start = 0
    end = 0
    max_length = 0
    char_set = set()

    # 滑动窗口
    while end < len(s):
        # 如果窗口中没有重复字符
        if s[end] not in char_set:
            # 将 max_length 更新为窗口的长度
            max_length = max(max_length, end - start + 1)
            # 将字符添加到哈希表中
            char_set.add(s[end])
            # 将窗口的结束位置向右移动一位
            end += 1
        # 如果窗口中存在重复字符
        else:
            # 将窗口的起始位置向右移动一位
            char_set.remove(s[start])
            start += 1

    # 返回最长子串的长度
    return max_length


# 测试用例
print(length_of_longest_substring("abcabcbb"))  # 3
print(length_of_longest_substring("bbbbbbb"))  # 1
print(length_of_longest_substring("pwwkew"))  # 3

结论

通过以上分析,我们对 LeetCode 第 3 号问题有了更深入的理解。我们学会了如何使用“滑动窗口”算法来解决此类问题,并将其应用到具体代码中。希望本文能对你的算法学习有所帮助。