这是O(N)的方法,维护窗口的左边和右边,右边不断向左走,当发现这个窗口里面有重复的时候,我们移动左边到重复元素的下一个,跳过中间的字符,因为不会比现在的max更长,而且也始终包含重复的字符。走到无重复了,我们继续移动右边。所以,表面看上去有while loop嵌套在另一个while loop里面,但是我们不重复之前走过的位置,所以时间复杂度还是O(N)的。
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;
while(runner < s.length()){
if(set.contains(s.charAt(runner))){
max = Math.max(runner-walker,max);
while(s.charAt(walker)!=s.charAt(runner)){
set.remove(s.charAt(walker));
walker++;
}
walker++;
}
else set.add(s.charAt(runner));
runner++;
}
max = Math.max(max,runner-walker);
return max;
}
下面是动态规划思维用hashset维护一个装满前面遇到的所有char的集合,只要集合增加我们的max就增加,一旦重复,就从头查看。但是因为是O(N*N)的时间复杂度,所以果断TLE过不了的囧。
public int lengthOfLongestSubstring(String s) {
if(s==null || s.length() == 0) return 0;
int len = s.length();
int i = 0;
int j = 1;
int max = 0;
HashSet<Character> set = new HashSet<Character>();
while(i < len) {
set.add(s.charAt(i));
j = i + 1;
while(j < len) {
if(!set.contains(s.charAt(j))) {
max = Math.max(j - i, max);
set.add(s.charAt(j));
j++;
//i++;
}
else {
set.clear();
break;
}
}
i++;
}
return max;
}