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

【解一】经典的滑动窗口既视感,需要维护窗口内没有重复的字母,所以我们可以直接做一个集合存一下窗口内现有的字母。如果窗口右侧更新了,需要维护左侧保证把重复的字母挪出窗口。在这个过程中记一下最长的长度。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if len(s)==0: return 0
        window = set(s[0])
        left = 0
        m = 1
        for i in range(1,len(s)):
            while s[i] in window:
                window.remove(s[left])
                left = left + 1
            if i-left+1 > m: m = i-left+1
            window.add(s[i])
        return m

【解二】直觉上对滑动窗口是一边更新右边一边维护左边的,如果遇到最坏情况那还是有冗余的。换一个思路想要一遍扫过它。对当前字母来说,破坏规则的最远距离就是前方离它最近的相同字母,如果我们更新一个字典记录这个字母最后的位置就可以算到这个最远距离了(如果没有被记录说明前面没有重复,最远距离就是i)。但是这个最远距离就是合法的距离嘛?显然不一定,因为俩字母中间可能会有别的不合法字母。我们可以维护一个目前的合法长度last,每次往后看一个字母,如果其最远距离小于目前长度,显然从最远距离处砍掉;如果最远距离大于目前长度,那么加上这个字母也合法,last+1。同样在扫过的过程中就记下最大值。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        pos = {}
        last = 0
        m = 0
        for i in range(0,len(s)):
            if s[i] in pos: l = i-pos[s[i]]-1
            else: l = i
            if l<last: last = l
            last = last + 1
            if last > m: m = last
            pos[s[i]] = i
        return m

【解三】这个解法效率上跟解二其实差不多,只是稍微换了下角度,我觉得写起来会简洁一点,提交结果上看也是快了一丢丢丢。基本原理一样的造一个字典存当前字母前面出现的位置,但是不用每次都计算长度了,我们直接维护序列开始的位置。这样就像滑动窗口一样,维护这个开始位置begin,如果字母上次位置在begin后面,直接掐到这个位置去,如果在前面则不影响不用变。当前-begin就是长度,记下最大值。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        pos = {}
        begin = -1
        m = 0
        for i in range(0,len(s)):
            if not(s[i] in pos): pos[s[i]] = -1
            if pos[s[i]]>begin: begin = pos[s[i]]
            if i-begin>m: m = i-begin
            pos[s[i]] = i
        return m
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值