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

示例 1:

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/probl...
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一种解法

暴力破解,创建两个变量start和end, 分别代表需要检查的无重复子串的开始位置和结束位置,变量n代表当前最长子串。
start变量从头到尾进行遍历,end变量从start变量起到尾进行遍历
计算,计算第end位置的变量是否存在于start到end-1位置的子串中,
存在即表示当前查找中的最长子串为end - start + 1

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        start = 0
        n = 0
        while start < len(s):
            end = start
            while end < len(s):
                if s[end] not in s[start:end]:
                    if (end - start + 1) > n:
                        n = end - start + 1
                else:
                    break
                end += 1
            start += 1
        return n

算法复杂度为O(n3)
空间复杂度为O(n)

第二种解法

滑快法,预设一个容量为n + 1的set变量从左至右滑动,n为当前已找到的最长不重复子串长度
当该set变量在设置容量下匹配不到新的子串,即找到最大的不重复子串长度n

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        length = len(s)
        if len(s) <= 0:
            return 0
        if len(s) == 1:
            return 1
        start = 0
        #最长不重复子串长度
        n = 1
        while n < len(s) and start < len(s):
            if len(set(s[start:start+n+1]).difference()) > n:
                n += 1
            else:
                start += 1
                continue
        return n

算法复杂度为O(n2), 空间复杂度为O(n)

可以继续优化,在遍历过程中,可以将将子串缓存进set()中,利用set列表的O(1)的查找复杂度,可以将算法优化至O(n)的复杂度

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        length = len(s)
        if len(s) <= 0:
            return 0
        if len(s) == 1:
            return 1
        start = 0
        end = 0
        result = set()
        n = 1
        while end < len(s) and start < len(s):
            if s[end] not in result:
                result.add(s[end])
                end += 1
                if (end - start) > n:
                    n = end - start
            else:
                if s[start] in result:
                    result.remove(s[start])
                start += 1
                continue
        return n

滑快在数组山不断调整滑动,平均算法复杂度为O(n)


海角七号
11 声望2 粉丝

喵~~~


« 上一篇
两数相加
下一篇 »
最小的k个数