384 最长无重复字符的子串
给定一个字符串,请找出其中无重复字符的最长子字符串。
样例
例如,在”abcabcbb”中,其无重复字符的最长子字符串是”abc”,其长度为 3。
对于,”bbbbb”,其无重复字符的最长子字符串为”b”,长度为1。
挑战
O(n) 时间
.
如果要实现O(n) 时间,必须一次遍历字符串。
用HashMap<字符,位置>储存每个字符的位置,用temp记录当前字符串长度。例如 “abcabcbb”
字符串 | Map | temp |
---|---|---|
a—-bcabcbb | {a:0} | 1 |
ab—-cabcbb | {a:0,b:1} | 2 |
abc—-abcbb | {a:0,b:1,c:2} | 3 |
abca—-bcbb | {a:3,b:1,c:2} | 3 |
abcab—-cbb | {a:3,b:4,c:2} | 3 |
abcabc—-bb | {a:3,b:4,c:5} | 3 |
abcabcb—-b | {a:3,b:6,c:5} | 2 |
abcabcbb | {a:3,b:7,c:5} | 1 |
-
i 是当前字符位置,i - temp是当前字符串起始位置。出现重复字符时,先判断字符上一次出现位置是否在当前字符串内,如果不在,则Map中更新位置并且temp++;如果在,则temp截断,从 上一次出现+1 的位置开始计算。
public class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> pos = new HashMap<>();
char[] ss = s.toCharArray();
int max = 0, temp = 0;
for(int i = 0; i < s.length(); i++){
if( !pos.containsKey(ss[i]) ){
pos.put(ss[i],i);
temp++;
}else{
if(pos.get(ss[i]) + temp < i){
temp++;
}else{
max = Math.max(max,temp);
temp = i - pos.get(ss[i]);
}
pos.put(ss[i],i);
}
}
max = Math.max(max,temp);
return max;
}
}