2018-12-13 LeetCode Q3 无重复字符的最长子串

5 篇文章 0 订阅
5 篇文章 0 订阅

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

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

样例:

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

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

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

窗口解法(608ms AC)
遍历这个字符串,
第一次:
当搜索到字符 s k s_k sk时,判断 s 0 到 s k − 1 s_0到s_{k-1} s0sk1中是否有字符与之重复,若 s j s_j sj重复,定义j为新的下界: u n d e r _ b o u n d under\_bound under_bound,tmp值初始为1,若 s j s_j sj s k s_k sk不同,则 tmp+=1 ,若相同,则跳出循环(break),此时最长子串长度为 m a x ( m a x _ l e n g t h , t m p ) max(max\_length, tmp) max(max_length,tmp)

第一次之后:
当搜索到字符 s k s_k sk时,判断 s u n d e r _ b o u n d 到 s k − 1 s_{under\_bound}到s_{k-1} sunder_boundsk1中是否有字符与之重复,若 s j s_j sj重复,定义j为新的下界: u n d e r _ b o u n d under\_bound under_bound, 其余关于tmp的累加和max_length的选择同上。

AC代码如下:

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        max_length = 0
        j = 0
        under_bound = -1
        while j < len(s):
            tmp = 1
            for k in range(j-1,under_bound,-1):
                if k != j and s[k] == s[j]:
                    under_bound = k
                    # print(s[k:j+1], under_bound)
                    break
                else:
                    tmp += 1
            j += 1
            max_length = max(max_length, tmp)
        return max_length

哈希解法(132ms AC)
不得不说字典是降低时间复杂度的治病良方(由于搜寻时间复杂度为 O ( l ) O(l) O(l)

考虑暴力解法:对于每一个字符 s k s_k sk,都寻找以它开头的不重复最长子串,而后找出最长的长度。是具有 O ( n 3 ) O(n^3) O(n3)时间复杂度的解法:遍历整个字符串——遍历从 s k s_k sk开始到发生重复的字符——比较判断字符 s j s_j sj s [ k : j ] s[k:j] s[k:j]中每个字符是否重复。

哈希解法的思路:创建一个字典,保留所有无重复字符的索引位置,当发生字符和字典中key重复时,更新索引位置,此时最大长度更新为当前位置和字典中存在的最小位置的距离。
代码如下:

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        #遍历一遍字符串,将没有重复的字母及其位置(如果有重复则保存最后出现的字母)保存至字典
        #用一个字典保存各个字母的位置
        #最长长度为 i - start + 1
        #start = 出现重复字母,旧的 + 1
        index = {}
        max_len = start = 0
        for i in range(len(s)):
            if s[i] in index:
                start = max(start,index[s[i]] + 1)
                #print(start,end="")
            index[s[i]] = i
            max_len = max(max_len , i - start + 1)
        return max_len
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值