返回

剑锋无畏所向披靡,无重复最长子串夺魁算法界

后端

前言

算法学习的征途上,我们免不了会遇到各种各样的算法题,而LeetCode便是其中最具代表性的平台之一。凭借其海量的题目数量和丰富多样的题型,LeetCode成为了众多程序员学习算法的必经之路。LeetCode上题目的种类之多也是令人眼花缭乱,但若要选出最热门的几道题,那么无重复字符的最长子串这一题绝对榜上有名。

无重复字符的最长子串题解

无重复字符的最长子串问题的核心在于,给定一个字符串s,找到其中不含重复字符的最长子串。这道题的难点在于如何高效地找出最长子串,如何在众多可能的子串中快速找出满足题意的子串。

滑动窗口法

滑动窗口法是解决无重复字符的最长子串问题最常用的一种方法。其基本思想是:使用一个窗口来表示当前子串,然后随着窗口的移动,不断更新子串。当窗口内出现重复字符时,窗口的起始位置向后移动一位,直到窗口内不包含重复字符为止。在这个过程中,我们记录下窗口内的最长子串长度,最后返回这个长度。

def lengthOfLongestSubstring(s):
    """
    :type s: str
    :rtype: int
    """
    # 定义滑动窗口的起始位置和最长子串长度
    start = 0
    max_length = 0

    # 使用哈希表记录每个字符最后出现的位置
    char_index_map = {}

    # 遍历字符串中的每个字符
    for i, char in enumerate(s):
        # 如果字符之前出现过,更新滑动窗口的起始位置
        if char in char_index_map and char_index_map[char] >= start:
            start = char_index_map[char] + 1

        # 更新字符最后出现的位置
        char_index_map[char] = i

        # 更新最长子串长度
        max_length = max(max_length, i - start + 1)

    return max_length

哈希表法

哈希表法是另一种解决无重复字符的最长子串问题的方法。其基本思想是:使用一个哈希表来记录每个字符最后出现的位置。当我们遍历字符串时,如果当前字符在哈希表中,并且其最后出现的位置大于或等于滑动窗口的起始位置,那么我们将滑动窗口的起始位置更新为当前字符最后出现的位置加一。同时,我们更新哈希表中该字符最后出现的位置。在这个过程中,我们记录下窗口内的最长子串长度,最后返回这个长度。

def lengthOfLongestSubstring(s):
    """
    :type s: str
    :rtype: int
    """
    # 定义哈希表
    char_index_map = {}

    # 定义滑动窗口的起始位置和最长子串长度
    start = 0
    max_length = 0

    # 遍历字符串中的每个字符
    for i, char in enumerate(s):
        # 如果字符之前出现过,更新滑动窗口的起始位置
        if char in char_index_map and char_index_map[char] >= start:
            start = char_index_map[char] + 1

        # 更新字符最后出现的位置
        char_index_map[char] = i

        # 更新最长子串长度
        max_length = max(max_length, i - start + 1)

    return max_length

总结

无重复字符的最长子串是LeetCode网站上最受欢迎的算法题之一。这道题的难点在于如何高效地找出最长子串,如何在众多可能的子串中快速找出满足题意的子串。

本文介绍了两种最有效的方法来解决无重复字符的最长子串问题:滑动窗口法和哈希表法。这两种方法都非常高效,能够在O(n)的时间复杂度内解决此问题。