题目
Given a string, find the length of the longest substring without repeating characters
Input: “abcabcbb”
Output: 3
Explanation: The answer is “abc”, with the length of 3.
Input: “bbbbb”
Output: 1
Explanation: The answer is “b”, with the length of 1.
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.
题解
暴力穷举
搜索所有子串,子串中不存在重复字符记录长度,时间复杂度O(n3)O(n^3)O(n3)
class Solution:
def isunique(self,substr):
sett=set()
for i ,c in enumerate(substr):
if c in sett:
return False
else:
sett.add(c)
return True
def lengthOfLongestSubstring(self, s: str) -> int:
maxlength=0
for i in range(len(s)):
for j in range(i+1,len(s)+1):
sub=s[i:j]
if self.isunique(sub) and maxlength<len(sub):
maxlength=len(sub)
return maxlength
滑动窗口法
创建一个滑动窗口,窗口首尾用i,j记录,使用集合记录此时窗口中的元素,当第j个元素不在集合中,添加进集合,同时窗口长度+1,当第j个元素在集合中,该窗口即j-i无效,此时长度-1,也就是i+1,集合中去除s[i],也就是窗口的起始位置向前移动一位,最长的窗口长度就是最长子串。时间复杂度O(n2)O(n^2)O(n2)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
sett=set()
i=j=0
ans=0
while i<len(s) and j <len(s):
if s[j] not in sett:
sett.add(s[j])
j+=1
ans=max(ans,j-i)
else:
sett.remove(s[i])
i+=1
return ans
滑动窗口优化
主要优化在,使用Hashmap记录这个字符最后一次出现的位置,同时如果在[i,j)中存在hashmap中的字符,位置在j′j^{'}j′中,那么I的位置改到j′j^{'}j′的位置。而不用一步一步的挪动。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
hashmap={}
i=j=0
ans=0
while i<len(s) and j<len(s):
if s[j] not in hashmap:
hashmap[s[j]]=j
j+=1
ans=max(ans,j-i)
else:
if hashmap[s[j]]+1<i:
ans=max(ans,j-i+1)
i=max(hashmap[s[j]]+1,i)
hashmap[s[j]]=j
j+=1
ans=max(ans,j-i)
return ans