python3
超时了,就是很传统的那种思路:每一种子串都检查一遍
时间复杂度极高
#
# @lc app=leetcode.cn id=3 lang=python3
#
# [3] 无重复字符的最长子串
#
# @lc code=start
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
res = []
res1 = []
s1=s
maxL=0
if len(list(set(s1))) == s1:
return len(s1)
else:
for i in range(len(s1)) :
for j in range(len(s1)-i):
res.append(s1[i+j])
lst = list(set(res))
#print(lst,res)
if len(lst)==len(res):#可能顺序不一样
if len(lst)>maxL:
res1=lst
maxL=len(res1)
#print("res1")
#print(res1)
res=[]
#lst = list(set(res1))
return maxL
# @lc code=end
采取滑动窗口的方法降低时间复杂度:图解算法
字符串只循环检查一遍,这样时间复杂度只有O(n)
定义一个可以左右拉长变短的窗口,放在字符串上(首位),
如果后面的字符不在该窗口里面,则窗口往右拉一位;
如果后面的字符被包含在该窗口里面,记录下该子串的长度(最长),
然后窗口左边拉到后面那个字符所在的下一个位置,重新拉,右边继续往后。
开始动手写代码就会发现,窗口的起始位置,与上次发现的队列中已经包含的重复元素的位置有关,
所以这个窗口应该设计一种数据结构(map),包含有值(val)、字符位置(loc)两个参数。
<然而我没写出来。。上面就是屁话>
他的思路是窗口每次只移动一位,数据结构使用元组代替,
只要里面有重复元素,就把最左边的元素删掉,然后向右移动一位继续判断。
#
# @lc app=leetcode.cn id=3 lang=python3
#
# [3] 无重复字符的最长子串
#
# @lc code=start
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
map = set()
start = 0
end = 0
maxL = 0
for i in range(len(s)):
end += 1
'''
if s[end] in map:
start = max(start,) #start应该是一样的那个字符的后一位
map = s[start,end]
else:
map.join(s[end])
'''
while s[i] in map:
map.remove(s[start])
start += 1
end -= 1
maxL=max(maxL,end)
map.add(s[i])
print(map,end)
return maxL
# @lc code=end
#测试用例:
#"abcabcbb" "bbbbb" "pwwkew"
#"a" "" "abcb" "dvdf" "AU"