Problem:
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.
思路:
首先想到的是暴力枚举,长度为N的字符串枚举所有的字串复杂度是N^2,检查有无重复字符又是N,一共是N^3。想都不用想,暴力肯定不行。
可以这样想,对于一个字符串str="ebacadcef",我们从头遍历,ebac是无重复字串(用哈希表记录是否有重复),当遍历到str[4],即ebaca时,有重复的两个a,之前知道的无重复字串最长是4。对于以str[0], str[1], str[2] 为开头的字串长度大于4是肯定不满足不重复的条件,因为在这些字串里我们确定有两个a。至于长度小于4的字串更不要考虑了。所以我们下一步要考录的子字符串起点在str[3]=c 处。继续在str[4]处向右遍历,在str[6]=c处我们又发现了重复的两个c (str[6]=str[3]=c)。str[3] 到 str[5] 的字串长为3,和之前的4比较,不如4大所以还保留4。下一步我们的子字符串起点是重复的第一个c的后面一位即str[4]=a处,而我们继续在str[6]处向后扫描源字符串,可以找到adcef,和之前的4比较,5>4,所以结果是5。扫描结束。
上代码
public class Solution {
public int lengthOfLongestSubstring(String s) {
if(s==null) return 0;
HashSet<Character> set = new HashSet<Character>();
int left = 0;
int res = 0;
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if(set.contains(c)){
while(s.charAt(left)!=c){
set.remove(s.charAt(left));
left++;
}
left++;
}else{
set.add(c);
res=Math.max(res, i-left+1);
}
}
return res;
}
}
这里用到了双指针,代码时间复杂度为O(n),空间用到了哈希表但只保存26个字符a-z可以认为是O(1).