LeetCode 3. Longest Substring Wi

2019-02-19  本文已影响0人  索毅

3. Longest Substring Without Repeating Characters

题目

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

知识点

  1. 错误解法:这种解法得到的是从第一个非重复字符开始的最长字串。
# -*- coding: utf-8 -*-
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        max_length = 0
        temp_length = 0
        old_word = set()
        # 对每一个字母
        # 1 如果之前出现过, 则判断temp_length是否大于max_length,set.clear,temp_length = 1 ,加入到set中。
        # 2 如果之前没出现过,则temp_length ++ ,加入到set中
        # 退出循环后, 判断temp_length是否大于max_length
        for i in s:
            if i in old_word:
                max_length = max(temp_length, max_length)
                old_word.clear()
                temp_length = 1
                old_word.add(i)
            else:
                temp_length += 1
                old_word.add(i)

        max_length = max(temp_length, max_length)
        return max_length


solution = Solution()
assert solution.lengthOfLongestSubstring("") == 0
assert solution.lengthOfLongestSubstring(" ") == 1
assert solution.lengthOfLongestSubstring("asc") == 3
assert solution.lengthOfLongestSubstring("aasc") == 3
assert solution.lengthOfLongestSubstring("bbbb") == 1
assert solution.lengthOfLongestSubstring("abcabcbb") == 3

assert solution.lengthOfLongestSubstring("dvdf") == 3 # 当出现重复字母时,clear时把需要的字串也去掉了

  1. 暴力方法,遍历所有子串,然后写个函数判断是否为不含重复字符子串,然后找最长的那个,复杂度为O(N^3),会超时
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        max_length = 0
        def check_unique(ss):
            old_word = set()
            for sss in ss:
                if sss in old_word:
                    return False
                old_word.add(sss)
            return True

        for i in range(0, len(s)):
            temp_s = s[i:]
            for j in range(0, len(temp_s) + 1):
                sub_s = temp_s[:j]
                if check_unique(sub_s):
                    max_length = max(max_length, len(sub_s))
        return max_length

解题 1

  1. 分析一下暴力方法的缺点和优化:
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        max_length = 0
        for i in range(0, len(s)):
            set_start_from_i = set()
            j = i
            while j < len(s):
                if s[j] in set_start_from_i:
                    break
                else:
                    set_start_from_i.add(s[j])
                    j += 1
            max_length = max(max_length, j - i)
        return max_length

解题 2

  1. 同样的原因,在每次s[j] in set,要更新i(右移左窗口)的时候,其实不需要把set清零。发现因为如果想把s[j]包含进来,必须不断左移i(set.pop(s[i]), i++),直到s[j] not in set。复杂度O(n)
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        i = 0
        j = 0
        window_content = set()
        max_len = 0
        
        while i < len(s):
            while j < len(s) and s[j] not in window_content:
                window_content.add(s[j])
                j += 1
            max_len = max(max_len, (j - i))
            if j == len(s):
                break
            else:
                while i < len(s) and s[j] in window_content:
                    window_content.remove(s[i])
                    i += 1
        return max_len
上一篇 下一篇

猜你喜欢

热点阅读