leetcode力扣第3题:无重复字符的最长子串(中等)

题目:

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

示例:
给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是 3。
给定 "bbbbb" ,最长的子串就是 "b" ,长度是 1。
给定 "pwwkew" ,最长子串是 "wke" ,长度是 3。请注意,你的答案必须是一个子串,"pwke" 是子序列不是子串。

解法思路:

首先想到的是暴力解法,在所有的子串中找出不含重复字符的,再求最长,可以用两个嵌套for循环来实现,但这种方式时间复杂度较高。

可以使用“滑动窗口”的方式,若窗口下一个字符与窗口子串中的字符不重复,则将其包含进去,窗口右界向右拓展1个长度。若若窗口下一个字符已经出现在窗口子串中,则重置窗口的左界位置到重复字符在窗口子串中所在位置的后一位。

我的解法:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if s == '': #判断空串
            return 0
        
        p = 0 #窗口左界
        q = 1 #窗口右界
        max_len = 1 #不重复子串的最大长度
        while q<len(s): 
            if s[q] in s[p:q]: #判断窗口的下一个字符是否已在窗口内出现
                p += s[p:q].index(s[q])+1 #更新窗口左界
                q += 1 #更新窗口右界
            else:
                q += 1 #更新窗口右界,无需更新左界
                if max_len< q - p:
                    max_len = q - p #更新最大长度
        return max_len

官方解法:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # 哈希集合,记录每个字符是否出现过
        occ = set()
        n = len(s)
        # 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
        rk, ans = -1, 0
        for i in range(n):
            if i != 0:
                # 左指针向右移动一格,移除一个字符
                occ.remove(s[i - 1])
            while rk + 1 < n and s[rk + 1] not in occ:
                # 不断地移动右指针
                occ.add(s[rk + 1])
                rk += 1
            # 第 i 到 rk 个字符是一个极长的无重复字符子串
            ans = max(ans, rk - i + 1)
        return ans

猜你喜欢

转载自blog.csdn.net/weixin_44458771/article/details/132072907