题目
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
思路
按顺序来,以pwkwkew为例子。
- p,长度为1=1-0
- pw 长度为2=2-0
- pwk 长度为3=3-0
- pwkw 不行,重复,kw,长度为2=4-2
- kwk 不行,重复 wk 长度为 2=5-3
- wke 长度为3=6-3
- wkew,不行,重复,kew,长度为3=7-4
这样就很清晰了,看出来关键是怎么安排后面的这几个数字。
现在位置 - 之前的起头的位置 = 长度
起头的位置最开始是0,当我们发现重复的时候更新,更新为上一次出现的重复的字符的序号,也就是第4步的时候吧原来的0更新成了2,在第2步的时候w出现了,把择出去就好了。
同理,在第5步的时候,要把k弄出去,就把后面的被减数改成3,k在第3步第一次出现。
python 程序循环内部:
if s[i] in dic:
start = max(dic[s[i], start)
如果这个值又出现了,那么我们就需要改变他的初始位置。
初始位置有两种可能:
要么是在上次出现的位置的下一个位置开始,如ABA,再开始就是BA,start = 2。
**要么是上次start的位置。**如ABB,再开始是B,start=3,因为之前的是表中的比较大而start还是0。再下一步如果是ABBA,这时候表里面的A的首次出现还是1,而上次的start已经是3了,所以再开始依然是从第二个B开始,start = 3。
out = max(out,i-start+1)
开始计算到底多长,两种可能:
abc这种越来越长:j-start+1
中间出现重复,要重新开始数,还是之前的长:out
dic[s[i]] = i+1
更新最后出现的位置。
程序结束,那么最终得到的就是就是最长子串。