返回

20天刷题计划——第3天:无重复字符的最长子串

后端

引言

在计算机科学中,字符串是一个由字符序列组成的有限有序集合。字符串的长度是指字符串中字符的数量。无重复字符的最长子串是指一个字符串中不包含重复字符的最长子串。

问题

给定一个字符串,求出该字符串中最长的无重复字符子串的长度。

例如,对于字符串 "abcabcbb",最长的无重复字符子串是 "abc",长度为 3。

思路分析

解决这个问题的一种方法是使用滑动窗口。滑动窗口是一种用于在字符串中查找子字符串的技术。滑动窗口的基本思想是使用一个固定大小的窗口在字符串中移动,并检查窗口内的字符是否重复。如果窗口内的字符不重复,则该窗口就是一个无重复字符子串。如果窗口内的字符重复,则将窗口向右移动一个字符,并重复检查窗口内的字符是否重复。

使用滑动窗口可以解决这个问题,具体步骤如下:

  1. 定义一个哈希表,用于存储窗口内的字符及其位置。
  2. 定义两个指针,一个指向窗口的左边界,另一个指向窗口的右边界。
  3. 将右指针向右移动,直到窗口内的字符不重复。
  4. 更新无重复字符子串的长度。
  5. 将左指针向右移动,并从哈希表中删除左指针指向的字符。
  6. 重复步骤 3 到 5,直到右指针到达字符串的末尾。

代码示例

def length_of_longest_substring(s):
    """
    计算字符串中最长的无重复字符子串的长度。

    参数:
        s (str): 字符串

    返回:
        int: 最长的无重复字符子串的长度
    """
    # 定义哈希表,用于存储窗口内的字符及其位置
    char_index_map = {}

    # 定义两个指针,一个指向窗口的左边界,另一个指向窗口的右边界
    left = 0
    right = 0

    # 定义无重复字符子串的长度
    max_length = 0

    # 将右指针向右移动,直到窗口内的字符不重复
    while right < len(s):
        # 如果当前字符不在哈希表中,则将其添加到哈希表中
        if s[right] not in char_index_map:
            char_index_map[s[right]] = right
            # 更新无重复字符子串的长度
            max_length = max(max_length, right - left + 1)
            # 右指针右移
            right += 1
        # 如果当前字符在哈希表中,则将左指针移动到当前字符的位置的右侧
        else:
            left = char_index_map[s[right]] + 1
            # 从哈希表中删除左指针指向的字符
            del char_index_map[s[left - 1]]

    # 返回无重复字符子串的长度
    return max_length


# 测试用例
s1 = "abcabcbb"
s2 = "bbbbb"
s3 = "pwwkew"

# 打印结果
print(length_of_longest_substring(s1))  # 3
print(length_of_longest_substring(s2))  # 1
print(length_of_longest_substring(s3))  # 3

改进时间复杂度的算法

上面给出的算法的时间复杂度为 O(n^2),其中 n 是字符串的长度。这可以通过使用更高级的算法来改进。例如,KMP算法和Manacher算法可以将时间复杂度降低到 O(n)。

总结

在本文中,我们详细分析了无重复字符的最长子串问题,并给出了一个使用滑动窗口的解决方案。此外,我们还探讨了改进时间复杂度的KMP算法和Manacher算法。这些算法可以帮助我们更有效地解决字符串处理问题。