LeetCode.3 Longest Substring Without Repeating Characters

题目简介:

给定一个字符串s,返回它的最长子串,并且子串中没有重复字符。下面举例:

字符串一:"abcabcbb" 返回:3

字符串二:"bbbb" 返回:1

字符串三:"pwwkeww" 返回:3

需要注意是,子串的顺序是不能更改的,像字符串三中,"pwke"就不是符合题意得子串。

解法一:最长字符串匹配

按照惯例,小天每次都会先介绍一种简单方法,题目既然要求输出最长子串,那么最简单的做法就是从最大可能地子串长度开始,不断遍历整个字符串,知道找到满足条件的子串。

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        i = len(set(s))
        n = len(s)
        flag = True
        while i > 0:
            for j in range(n - i + 1):
                sub = s[j: j + i]
                if len(set(sub)) == i:
                    flag = False
                    break
            if flag == False:
                break
            i -= 1
        return i

解法一实际上还是一种暴力求解法,最差的情况下,尽管子串中出现过的字符数量为n,但是却需要尝试所有的可能性。这道题LeetCode上基准测试耗时为444 ms。

解法二:一次匹配

对算法的优化无非从时间复杂度和空间复杂度上着手,这道题怎么降低到线性复杂度呢?小天这里为同学们提供一种思路:

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        sub = []
        max_sub = 0
        for c in s:
            if c not in sub:
                sub.append(c)
            else:
                for i in range(len(sub)):
                    if sub[i] == c:
                        break
                if len(sub) > max_sub:
                    max_sub = len(sub)
                sub = sub[i + 1:]
                sub.append(c)
        if len(sub) > max_sub:
            max_sub = len(sub)
        return max_sub

sub是当前时刻子串,每遍历到一个字符,如果不存在子串中,就添加至最后。如果存在,则截取sub在该字符之后的部分作为新的sub,当然,不要忘了添加该字符。解法二的主循环保证时间复杂度降至线性,基准测试上耗时为100ms。

解法二显然不是最优的,为找到字符在list类型上的index,实现有点复杂了。State of the Art解法用了一种字典格式存储当前子串,用begin和res两个指示符代替子串内的搜索。有兴趣的同学可以上LeetCode看一下!

总结:

python中的for关键词耗时比较大,在实现中尽可能避免。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值