难度: Medium
原题连接
内容描述
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 - 时间复杂度: O(N)- 空间复杂度: O(N)******
slide window, beats 67.09%
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
if not s or len(s) == 0:
return 0
l, r = 0, 0
res, lookup = 0, set()
while l < len(s) and r < len(s):
if s[r] not in lookup:
lookup.add(s[r])
res = max(res, r-l+1)
r += 1
else:
lookup.discard(s[l])
l += 1
return res
思路 2 - 时间复杂度: O(N)- 空间复杂度: O(N)******
思路
粗一看是 dp,细一看是 greedy
我们先从第一个字符开始,只要碰到已经出现过的字符我们就必须从之前出现该字符的index开始重新往后看。
例如‘xyzxlkjh’,当看到第二个‘x’时我们就应该从y开始重新往后看了。
那么怎么判断字符已经出现过了呢?我们使用一个hashmap,将每一个已经阅读过的字符作为键,而它的值就是它在原字符串中的index,如果我们现在的字符不在hashmap里面我们就把它加进hashmap中去,因此,只要目前的这个字符在该hashmap中的值大于等于了这一轮字符串的首字符,就说明它已经出现过了,我们就将首字符的index加1,即从后一位又重新开始读,然后比较目前的子串长度与之前的最大长度,取大者。
- res 代表目前最大子串的长度
- start 是这一轮未重复子串首字母的 index
- maps 放置每一个字符的 index,如果 maps.get(s[i], -1) 大于等于 start 的话,就说明字符重复了,此时就要重置 res 和 start 的值了,
beats 74.35%
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
res, start, n = 0, 0, len(s)
maps = {}
for i in range(n):
start = max(start, maps.get(s[i], -1)+1)
res = max(res, i - start + 1)
maps[s[i]] = i
return res
思路 3 - 时间复杂度: O(N)- 空间复杂度: O(N)******
slide window 全家桶,第159题和第340题几乎一摸一样,改几个数字就AC了,堪称模版
beats 70.56%
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
lookup = collections.defaultdict(int)
l, r, counter, res = 0, 0, 0, 0
while r < len(s):
lookup[s[r]] += 1
if lookup[s[r]] == 1:
counter += 1
r += 1
# counter < r - l 说明有重复字符出现,正常为counter == r - l
while l < r and counter < r - l:
lookup[s[l]] -= 1
if lookup[s[l]] == 0:
counter -= 1
l += 1
res = max(res, r - l)
return res