標籤:hash java leetcode map substring
第三道題Longest Substring Without Repeating Characters如下:
Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.
圖一、本題視窗掃描
思路:如(畫得不好請見諒)。維護一個視窗[walker,runner]:
一、視窗區間上限runner跑在前面,每掃描一次,將對應的元素添加至HashSet裡,直到掃描到HashSet裡已經存在的元素,runner停下,記為runner1。等一等走得比較慢的walker。此時,視窗記憶體在與walker處相同的元素;
二、首先記錄walker與runner的距離,因為此時walker往前的子字串都是無元素重複的,與max比大小。緊接著,walker也不能落後,走了起來,一直到與runner一樣元素的地方。邊走邊把之前那些元素從HashSet裡丟掉,直到找到那個與runner1元素相同的地方,記為walker1。walker1前面部分丟掉的原因是不可能找到一個包含[walker1,runner1]區間的再大的區間使得其實無重複的,因為[walker1,runner1]區間內已有重複元素。所以求下一個目標區間只能往前走,把下區間丟掉,此時去到第三步;
三、把walker1前面(包括自身)丟掉後,問題回到了第一步,重複第一步的過程即可。
Java代碼如下;
public class Solution { public int lengthOfLongestSubstring(String s) { if(s==null && s.length()==0) return 0; HashSet<Character> set = new HashSet<Character>(); int max = 0; int walker = 0; int runner = 0; for(;runner<s.length();runner++) { if(set.contains(s.charAt(runner))) { max = (runner-walker)>max?(runner-walker):max; while(s.charAt(walker)!=s.charAt(runner)) { set.remove(s.charAt(walker)); walker++; } walker++; } else { set.add(s.charAt(runner)); } } max = (runner-walker)>max?(runner-walker):max; return max; } }
學習參考:
[1]. LeetCode – Longest Substring Without Repeating Characters (Java)
[2]. Repeating Characters -- LeetCode
LeetCode【3】.Longest Substring Without Repeating Characters--演算法圖解及java實現