3 Longest Substring Without Repeating Characters(无重复字符的最长子串)Python实现

版权申明:原创文章,未经博主同意,不得转载!

Longest Substring Without Repeating Characters(无重复字符的最长子串),其内容如下:

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

示例 1:

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

示例 2:

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

示例 3:

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

仔细阅读题目,要求是在给定的字符串中找到最长的无重复字符子串,题目给了三个示例,已经很明白的说明了要求。下面我们就思考如何解决这个问题。对于我们来说,给定一个字符串,如示例1中“abcabcbb”,如何寻找最长无重复子串呢?肯定要从给定的字符串起点开始向后遍历,一直遇到已经出现过的字符,如a,b,c,a,这时又出现a,出现了重复字符,我们可以记录当前的最长子串长度为3。

在示例1中,第一次出现的重复字符是a,是在当前记录子串的第1位,我们不妨假设一下,如果出现的字符不是a而是b或c呢?

3 Longest Substring Without Repeating Characters(无重复字符的最长子串)Python实现_第1张图片
可以看到,这样三种情况已经包含了重复字符出现的所有位置,针对更长的子串也是这样,就是开头、中间和尾部三种情况。但不论重复字符出现在哪个位置,它都表示当前记录子串的结束。而对于出现的重复字符位置,其实可以归结为一种情况,可以将其看做为寻找下一子串的起点。
3 Longest Substring Without Repeating Characters(无重复字符的最长子串)Python实现_第2张图片

按照上面的思路,编写了如下代码:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # 记录当前子串的长度
        length = 0
        # 记录当前无重复字符最长子串的长度
        maxlen = 0
        # 遍历字符串
        for i in range(len(s)):
            # 设定当前子串长度为1
            length = 1
            # 从指定起始位置开始遍历
            for j in range(i+1, len(s)):
                # 如果当前字符重复字符
                if s[j] in s[i:j]:
                    # 指定下一子串遍历位置,跳出循环
                    i += (s[i:j].index(s[j])+1)
                    break
                # 不是重复字符
                else:
                    # 当前子串长度加1
                    length += 1
            # 记录最大长度
            if length > maxlen:
                maxlen = length
        return maxlen

运行结果:

3 Longest Substring Without Repeating Characters(无重复字符的最长子串)Python实现_第3张图片

感觉我们的方法还是可以的啊,但是为什么速度这么慢?还是算法有问题吗。所以赶紧找网上的大神博客看一下,LeetCode官方也提供了题解。官方题解

看了之后,我们的方法可以称之为滑动窗口。而且我们的算法还可以进一步优化。当我们遇到重复字符之后,我们得到了下一子串的起点位置,但是我们并不需要在从起点位置进行遍历,因为我们可以确定在起点到当前重复字符之间没有其他重复字符,所以我们可以直接从重复字符位置作为向后遍历的起点。
3 Longest Substring Without Repeating Characters(无重复字符的最长子串)Python实现_第4张图片

修改代码:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # 记录当前无重复字符最长子串的长度
        maxlen = 0
        i = 0
        # 遍历字符串
        for j in range(0, len(s)):
            # 出现重复字符
            if s[j] in s[i:j]:
                # 指定下一子串遍历起点位置
                i += (s[i:j].index(s[j])+1)
            # 无重复字符
            else:
                # 更新最大长度
                maxlen = max(maxlen, j-i+1)
        return maxlen

在代码中,我们去掉了最外层循环,原来的内层循环使用相对位置现在变为绝对位置,改变了最大长度值的更新方式。

运行结果:
3 Longest Substring Without Repeating Characters(无重复字符的最长子串)Python实现_第5张图片

还是要多学习别人的方法,这样的写出来的代码颜值高而且有内涵。

这道Longest Substring Without Repeating Characters的解法就介绍到这里。

以上。

本期到此结束,扫下面二维码加Python学习公众号,有海量优质学习资源!
3 Longest Substring Without Repeating Characters(无重复字符的最长子串)Python实现_第6张图片

你可能感兴趣的:(Python,for,LeetCode)