leetcode 无重复字符的最长子串
题目描述:
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
解一:暴力搜索
从输入字符串s中找到所有子串,然后判断每个子串中有无重复字符,找到没有重复字符的最长子串。
def lengthOfLongestSubstring(self,s): if len(s)==0: return 0 strlen = len(s) maxlen = 0 for i in range(strlen): for j in range(i+1,strlen): for k in range(i,j): temp=s[i:j+1] flag = 0 templen = len(temp) for m in range(templen): for n in range(templen): if temp[m]==temp[n] and m!=n: flag=1 if flag==0: mylen = j-i+1 if mylen>maxlen: maxlen=mylen return maxlen
测试样例结果正确,提交超时。
解二:改进版的暴力搜索
只考虑和寻找没有重复字符的子串
同样从字符串s第一个字符开始,定义一个临时的字符串temp,初始为空,从位置i开始搜索,若该字符在temp中没有出现过,将其加入temp,否则i移动到下一个位置
def lengthOfLongestSubstring(self,s): slen = len(s) maxlen=0 for i in range(slen): temp = "" count=0 for j in s[i:]: if j not in temp: temp=temp+j count=count+1 if count>maxlen: maxlen=count else: break return maxlen
解三:滑动窗口法(利用字典hash表的查询优势)
定义last={}保存在字符串中出现过的字符和其位置,left记录当前窗口的左边界。
从s第一个字符开始,若当前字符不在last中则加入,并记录当前字符位置i与当前窗口左边界left间字符串长度。
若当前字符在last中已存在,则更新左边界以及该字符的last位置。
一个示例如下:
即left代表当前窗口左边界,右边界随i移动,left保存当前窗口中出现的字符及位置,当读入的下一个字符在last即当前窗口中存在时,更新left进入下一个窗口。
class Solution(object):
def lengthOfLongestSubstring(self,s):
last = {}
left = 0
ans = 0
for i in range(len(s)):
if s[i] in last and last[s[i]]>=left:
left = last[s[i]]+1
last[s[i]]=i
ans = max(ans,last[s[i]]-left+1)
return ans
参考:
https://www.yuanrenxue.com/tricks/leetcode-longest-substring.html