第三道題如下:
- ** 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.*
思路:如上圖(畫(huà)得不好請(qǐng)見(jiàn)諒)。維護(hù)一個(gè)窗口[walker,runner]:
一、窗口區(qū)間上限runner跑在前面,每掃描一次,將對(duì)應(yīng)的元素添加至HashSet里,直到掃描到HashSet里已經(jīng)存在的元素,runner停下,記為runner1。等一等走得比較慢的walker。此時(shí),窗口內(nèi)存在與walker處相同的元素;
二、首先記錄walker與runner的距離,因?yàn)榇藭r(shí)walker往前的子字符串都是無(wú)元素重復(fù)的,與max比大小。緊接著,walker也不能落后,走了起來(lái),一直到與runner一樣元素的地方。邊走邊把之前那些元素從HashSet里丟掉,直到找到那個(gè)與runner1元素相同的地方,記為walker1。walker1前面部分丟掉的原因是不可能找到一個(gè)包含[walker1,runner1]區(qū)間的再大的區(qū)間使得其實(shí)無(wú)重復(fù)的,因?yàn)閇walker1,runner1]區(qū)間內(nèi)已有重復(fù)元素。所以求下一個(gè)目標(biāo)區(qū)間只能往前走,把下區(qū)間丟掉,此時(shí)去到第三步;
三、把walker1前面(包括自身)丟掉后,問(wèn)題回到了第一步,重復(fù)第一步的過(guò)程即可。
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;
}
}
學(xué)習(xí)參考:
[1]. LeetCode – Longest Substring Without Repeating Characters (Java)
[2]. Repeating Characters -- LeetCode