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

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

python 无重复字符的最长子串 Leetcode No.3_第1张图片

题意

刚开始看到这个题目的是,下意识觉得会用动态规划写,动态规划有个经典题目,就是求两个字符串的公共最长子序列,感觉很像。anyway,哈哈哈哈。
思路:

  1. 第一种暴力解法,不说了
  2. 第二种滑动窗口,先尝试选取一个合适的滑动窗口的大小,比如第一个例子中初步定下来是abc然后我们就往里面加后续的字母,比如往abc的滑动窗口中加入a,会发现里面有了,那就把最左边移出取,把a加入进去,如果滑动窗口的长度不变,那不就代表,a是出现在最左边的,变了(其实变与不变都一样操作,应该我们只需要找到长度大于3的,用set存完会去重),就继续上述的操作,直到找到一个长度为3的滑动窗口,然后继续往里面添加元素,如果已知不变,那么最长的滑动窗口就是3了。
  3. 第三种方法是优化的滑动窗口,从第二种方法我们知道,如果发现又一个元素已经在set里面出现了,我们是移除掉最左边的元素。而第三种方法是,直接把滑动窗口的最左边移动到,存在的元素。eg:abcacbb,起初的滑动窗口是abc,然后发现a在里面,那我们找到a的index,移动到他的前面,也就是现在的滑动窗口是bca了(我们记录了最大的滑动窗口的数字),然后我们发现c也在里面,那么移动到它的前面,现在的滑动窗口是ac,虽然比前面的三个少了,但是没有关系,因为我们已经记录下最大的滑动窗口,那为什么这么做呢,因为当你发现了一个元素已经出现过了,那你无论怎么移动窗口,那么窗口的大小要不就是和以前一样大,要不就是比以前小,那不如直接移动到,出现元素的前面,重新开始添加元素。(有点字符串匹配中kmp算法的思想,感兴趣的了解一下)
#第二种方法
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        n = len(s)
        ans = i = j =0
        longth_set = set()
        while (i<n) and (j<n):
            if s[j] not in longth_set:
                longth_set.add(s[j])
                j+=1
                ans = max(ans,j-i)
            else:
                longth_set.remove(s[i])
                i+=1
            print(longth_set)
        
        return ans
        
    
#第三种方法
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        res = i = 0
        for j in range(len(s)):
            if s[j] not in s[i:j]:
                res = max(res, j+1-i)
            else:
                i += s[i:j].index(s[j]) + 1
        return res
    

你可能感兴趣的:(python,LeetCode,面试,Python,LeetCode,NO.3,无重复字符的最长子串)