給定一個字符串 s ,請你找出其中不含有重復(fù)字符的 最長子串 的長度。
輸入: s = "abcabcbb"
輸出: 3
解釋: 因為無重復(fù)字符的最長子串是 "abc",所以其長度為 3贫途。
輸入: s = "pwwkew"
輸出: 3
解釋: 因為無重復(fù)字符的最長子串是 "wke",所以其長度為 3待侵。
請注意丢早,你的答案必須是 子串 的長度,"pwke" 是一個子序列诫给,不是子串香拉。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán)中狂,非商業(yè)轉(zhuǎn)載請注明出處凫碌。
解釋下: 子串是一段連續(xù)的字符。 子序列不是胃榕,
重點來了:
這個題目只是需要找到最大長度盛险,而不是要找出對應(yīng)的字符串。
這個最大長度一直都在變化中勋又,是一直都在比較苦掘。
max 是一直都在變化中的,我們只是保存最大的而已楔壤。
使用2個指針鹤啡,和滑動窗口
1:fast slow 指針,一開始都指向0蹲嚣。如果沒有重復(fù)的递瑰,那fast 指針就向后移動一位
2:使用map來判斷當前元素是否已經(jīng)存在,
3:如果當fast 遇到有重復(fù)的數(shù)據(jù)了隙畜,例如現(xiàn)在fast在下標10抖部。slow在下標5。當fast移動到下標11的時候议惰,發(fā)現(xiàn)11和5重復(fù)了(也就是fast和slow對應(yīng)的值一樣了)慎颗,那么就移動slow指針,
將它移動到上一次出現(xiàn)位置的下一個位置,也就是移動slow 到 map.get(slow)+1 的位置上俯萎。 因為5-10是不重復(fù)的傲宜,5和11重復(fù),那么6-11 就是不重復(fù)的數(shù)據(jù)讯屈。
max=fast-slow +1 蛋哭。因為這個題目是一直都在遍歷中县习,所以每次都要用max來比較涮母,
所有max=Math.max(max,slow-fast+1);
如果數(shù)據(jù)是 abca 當a再加入進去的時候,上一次指向a是0 這次應(yīng)該移動到1 有效的字符串應(yīng)該是bca 此時左指針應(yīng)該是 get(b)+1=1
如果數(shù)據(jù)是 abba 當b再進去的時候躁愿,此時 上一次指向b的是1 這次應(yīng)該是移動到2叛本。字段變?yōu)榱薭 當a 再加上去的時候,發(fā)現(xiàn)又出現(xiàn)了重復(fù)彤钟,第一次a是0 現(xiàn)在a是3
那么按照道理 slow 要從2變?yōu)?+1 到1 了来候,就變成了會退。相當于慢指針往后走了逸雹,實際上應(yīng)該不變营搅,最后字段是ba 才對。
為了處理問題梆砸。
我們每次獲取slow=map.get(重復(fù)字符)+1 都要與當前的slow 對比转质,
例如 abba 第一次b 重復(fù)了 slow =map.get(b)+1=2 此時的max=2-1+1=2
第二次a 重復(fù)了 按照邏輯就是slow=map.get(a)+1=0+1=1 但是上一次slow 已經(jīng)變成了2 如果回退,那字段就是 bba了帖世。本身就重復(fù)了休蟹,所以我們需要對slow進行比較,
slow=Math.max(slow,map.get(重復(fù)字符)+1); 這次slow就還是2日矫,此時max=2-2+1=1 因為max是一直在變化赂弓,所以max=2 字段變?yōu)榱薭a
解決了abba的問題后,每一次遍歷字符的時候哪轿,都應(yīng)該更新下 當前字符 以及他的下標盈魁。
更新的重點在于下標,主要是因為只有通過下標定位窃诉,你才能知道上一次重復(fù)字段的下標是多少
public int lengthOfLongestSubstring3(String s) {
int max=0;
int len=s.length();
int left=0;
Map<Character,Integer> map=new HashMap<>(len);
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if(map.containsKey(c)){
left=Math.max(left,map.get(c)+1);
}
map.put(c,i);
max=Math.max(max,i-left+1);
}
return max;
}