LeetCode Go - 3. 无重复字符的最长子串

5,368 阅读2分钟

这是我参与更文挑战的第18天,活动详情查看:更文挑战

为了更好的明天,坚持刷 LeetCode

题目

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

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

示例 4:

输入: s = ""
输出: 0

提示:

0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成

解法一 - 滑动窗口

解题思路

每次循环时将每个字符存入哈希表中,当在哈希表中找到相同字符的时候,结束一次循环,并将哈希表的长度与当前的最长子串的长度作比较(一开始为 0),取较大者,同时重置哈希表,进行下一次循环。

外层循环从 0 开始,内层循环从外层循环的下标 +1 开始。

代码

func lengthOfLongestSubstring(s string) int {
    m := make(map[byte]bool)
    l := 0
    for i, _ := range s {
        m[s[i]] = true
        for j := i+1; j < len(s); j++ {
            if _, found := m[s[j]]; found {
                if l < len(m) {
                    l = len(m)
                }
                m = make(map[byte]bool)
                break
            }
            m[s[j]] = true
        }
    }
    if l < len(m) {
        l = len(m)
    }
    return l
}

执行结果

执行用时:364 ms,在所有 Go 提交中击败了 5.03% 的用户
内存消耗:7 MB,在所有 Go 提交中击败了 5.29% 的用户

复杂度分析

  • 时间复杂度:O(N),其中 N 是字符串的长度。下标 ij 分别会遍历整个字符串一次。
  • 空间复杂度:O(∣Σ∣),其中 Σ 表示字符集(即字符串中可以出现的字符),∣Σ∣ 表示字符集的大小。在本题中没有明确说明字符集,因此可以默认为所有 ASCII 码在 [0, 128) 内的字符,即 ∣Σ∣=128。我们需要用到哈希集合来存储出现过的字符,而字符最多有 ∣Σ∣ 个,因此空间复杂度为 O(∣Σ∣)。

题目链接

3. 无重复字符的最长子串