返回

找出字符串中不含有重复字符的最长子串-踩坑

前端

引言

在算法实践中,我们经常会遇到处理字符串的问题。其中,找出字符串中不含有重复字符的最长子串是一个经典且重要的算法问题。掌握解决这类问题的技巧,不仅可以提升我们的算法能力,在实际工作中也能派上用场。

算法思路

为了找出字符串中不含有重复字符的最长子串,我们可以采用滑动窗口的思想。具体而言,我们维护一个滑动窗口,窗口的左边界和右边界分别表示子串的起始位置和结束位置。当窗口中没有重复字符时,我们右移右边界,扩大窗口。一旦窗口中出现重复字符,我们左移左边界,缩小窗口。通过不断移动边界,我们可以找到不含有重复字符的最长子串。

Python实现

def longest_substring_without_repeating_characters(s):
    """
    找出字符串中不含有重复字符的最长子串的长度

    参数:
    s: 输入字符串

    返回:
    最长子串的长度
    """
    # 哈希表,记录字符最后出现的位置
    char_index_map = {}
    # 滑动窗口的左边界和右边界
    left, right = 0, 0
    # 最长子串的长度
    max_length = 0

    while right < len(s):
        # 如果当前字符已在窗口中出现过
        if s[right] in char_index_map:
            # 更新左边界为上次出现位置 + 1
            left = max(left, char_index_map[s[right]] + 1)

        # 更新当前字符的最后出现位置
        char_index_map[s[right]] = right

        # 更新最长子串的长度
        max_length = max(max_length, right - left + 1)

        # 右移右边界
        right += 1

    return max_length

踩坑点

在使用continue语句时,要注意两个语句中的区别:

  • continue:表示跳过当前循环的剩余部分,继续执行下一次循环。
  • continue inner:表示跳过当前嵌套循环的剩余部分,继续执行外层循环。

如果不小心使用了错误的continue语句,可能会导致代码逻辑混乱,从而踩坑。

示例

假设我们有一个字符串s = "abcabcbb"。使用上面提供的算法,我们可以得到:

  • 初始时,滑动窗口为""left = 0right = 0
  • 遍历到s[0] = "a",更新char_index_mapleft = 0right = 1
  • 遍历到s[1] = "b",更新char_index_mapleft = 0right = 2
  • 遍历到s[2] = "c",更新char_index_mapleft = 0right = 3
  • 遍历到s[3] = "a",由于a已在窗口中出现过,更新left = 1right = 4
  • 遍历到s[4] = "b",由于b已在窗口中出现过,更新left = 2right = 5
  • 遍历到s[5] = "c",由于c已在窗口中出现过,更新left = 3right = 6
  • 最终,得到最长子串为"abc",长度为3

总结

通过本文的讲解,我们了解了如何使用滑动窗口算法找出字符串中不含有重复字符的最长子串的长度。同时,我们也分析了使用continue语句时容易踩的坑,帮助读者避免此类错误。掌握这些知识点,不仅可以提升我们的算法能力,在实际工作中也能更加高效地解决问题。