003——无重复字符的最长子串

003——无重复字符的最长子串

1.题目

在这里插入图片描述

2.我的解决办法

  • 思路
    • 使用列表作为滑动窗口
    • 使用i,j作为窗口的开始和结束指针
    • 碰到重复/遍历到字符串末尾清空窗口,统计窗口最大值
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        ls = []     # 定义空列表作为滑动窗口
        max_len = 0 # 最大长度
        count = 0   # 滚动统计数
        if len(s) == 1: # 当字符串长度为1
            return 1
        for i in range(len(s)): # 当字符串长度大于1
            if max_len <count:  # 内循环终止的情况2:没有碰到重复且遍历到字符串末尾,这时需要进行比较
                max_len = count
            ls.clear()  # 当i指针更换时,列表清零,重新计数
            count = 0
            ls.append(s[i])
            count += 1
            for j in range(i+1, len(s)):
                if s[j] in ls:  # 内循环终止的情况2:碰到重复,这是需要进行比较
                    if(max_len < count):
                        max_len = count
                    count = 0
                    break
                ls.append(s[j])
                count += 1
        return max_len

3.官方的解决办法

3.1 第一种解决办法

  • 反思:最大的区别在于,官方的解决方案在左指针发生更换的时候,并没将窗口长度清除为0,而是在原来的基础之上增大窗口的长度再进行尝试
  • 当发生重复之前,窗口内是不重复的,所以没有必要用clear将右指针进行改变
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

3.2 第二中解决办法

  • 左侧指针从k从-1开始
  • 需要查找,所以尝试用哈希
  • 右指针i递增将不重复元素的依次放入哈希表,遍历到新元素再哈希表中出现,说明重复,将左指针更新为与新元素重复的这个元素的下标,计算子串长度进行比较
  • 优点在于左指针是跳跃前进的,不是依次遍历
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        k, res, c_dict = -1, 0, {}
        for i, c in enumerate(s):
            if c in c_dict and c_dict[c] > k:  # 字符c在字典中 且 上次出现的下标大于当前长度的起始下标
                k = c_dict[c]
                c_dict[c] = i
            else:
                c_dict[c] = i
                res = max(res, i-k)
        return res
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值