leetcode--无重复字符最长子串

前言:

最近有重新开始在LeetCode上刷题,刚好可以写写博客,和同学交流一下解题思路。解题用的语言一般会用Python ,偶尔使用C++。不过今天还是超级开心的,半年,对于我来说是一个新的起点,对于是否有一个好的未来,我也只剩半年的奋斗时间了。冲鸭,话不多说!开始解题。

题目:

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

示例 1:

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

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

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

思路:

一开始的思路是用两个指针追踪字符的长度,一个整型变量来记录最长的长度数值。如有用Python实现时,看了一下别人的滑窗思想,决定新建两个字符来记录内容,便于我输出查看便利的字符串内容。直接上代码:


代码:

class Solution(object):

def lengthOfLongestSubstring(self, s):
    """
    :type s: str
    :rtype: int
    """
    nstr = "" #记录即时的子字符串内容
    mstr = "" #记录最长子串的内容
    for i in s :
        if i in nstr:
            if len(nstr) > len(mstr):
                    mstr = nstr #更新最长的子串
            index = nstr.index(i)
            nstr = nstr[index+1:]#进行滑窗,将重复字符前的内容删除
        nstr += i #若字符不在nstr中则追加


    strlen = len(mstr)
    if len(mstr) < len(nstr): #判断遍历完后,mstr与nstr的长度
        strlen = len(nstr)
    return strlen

最后执行时间为88ms,有一点小慢,于是想了一下怎么去改进,首先原本的程序表面上看起来的时间复杂度是O(n),但是做 in 判断时会进行遍历,于是的我的想法就是在索引判断这入手,想到的方法是应用字典,因为字典是Python的一种映射的容器,索引查找可以说快得不要不要的。上代码:


代码:

class Solution(object):

def lengthOfLongestSubstring(self, s):
    """
    :type s: str
    :rtype: int
    """

    dic = {}
    start = -1
    maxlen = 0
    for i in range(len(s)):
        if s[i] not in dic :
            dic[s[i]] = -1
        start = max([start,dic[s[i]]])
        maxlen = max(maxlen,i-start)
        dic[s[i]] = i

    return maxlen

确实程序快了不少,来到了76ms

不过在Python提交的用户中,还有40几%的人写的程序比我快,我便开始从我的算法结构进行思考,但是始终觉得这种hash索引的方式已经是最快的了。我便去搜了一下别人写的代码,才发现自己的关注点出现了问题。

52ms的执行代码:

class Solution(object):

def lengthOfLongestSubstring(self, s):
    """
    :type s: str
    :rtype: int
    """

    record_place = {}
    max_len = 0
    mid_max_len = 0
    for (i, ch) in enumerate(s):
        if ch not in record_place:
            mid_max_len += 1
            if max_len < mid_max_len:
                max_len = mid_max_len
        else:
            if i - record_place[ch] > mid_max_len:
                mid_max_len += 1
                if mid_max_len > max_len:
                    max_len = mid_max_len
            else:
                mid_max_len = i - record_place[ch]

        record_place[ch] = i
    return max_len

对比别人的代码,可以发现我的代码的速度差异在于,我的代码重复建立列表用列表的max方法进行比较。从中也可以看出来我对Python的内存机制与一些常用函数的使用还不够了解。还是要多看书,多学习


今日情感电台:

“世人跟你讲体面,讲成为大人的道理,一点点错失都会被无情扣分。但在我这不一样,我给你的爱是兜底,所以你不用做那个听话才能得到奖励的小朋友,就算你耍小脾气,我也最最偏心你”

很幸运有一个人和自己一起努力

赏瓶可乐吧(*^▽^*)