12/10
遍历字符串
维护一个临时字符串和最长子串的长度
临时字符串将尝试所有连续无重复字符的情况。
用hashmap保存各个字符上次出现的下标
若遍历到的字符又出现,将目前的字符串的头指针移动到该字符上次出现的后一位
class Solution {
public int lengthOfLongestSubstring(String s) {
int ans=0;
int now=0;
int st=0;
Map<Character,Integer>mp=new HashMap<>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if(mp.containsKey(ch)==false){
now++;
}else{
int fin=mp.get(ch);
for(int j=st;j<fin;j++){
mp.remove(s.charAt(j));
}
now-=fin-st;
st=fin+1;
}
mp.put(ch,i);
ans=Math.max(ans,now);
}
return ans;
}
}
简单优化
不需要每次修改临时字符串的起点时,删除旧起点和新起点之间的映射关系。我们只需要保存上一次该字符出现的下标位置。
若是检测到的key的value小于st那么,就代表他已经不在临时字符串中,滑动窗口的左侧直接跳跃
class Solution {
public int lengthOfLongestSubstring(String s) {
int ans = 0;
int now = 0;
int st = 0;
Map<Character, Integer> mp = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (mp.getOrDefault(ch, -1) < st) {
now++;
} else {
int fin = mp.get(ch);
now -= fin - st;
st = fin + 1;
}
mp.put(ch, i);
ans = Math.max(ans, now);
}
return ans;
}
}
再优化:hashmap变字符串,index为ascll码
通过下标+1来规避掉下标为0的情况
class Solution {
public int lengthOfLongestSubstring(String s) {
int ans = 0;
int now = 0;
int st = 0;
int[] asc = new int[128];
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (asc[ch] - 1 < st) {
now++;
} else {
int fin = asc[ch] - 1;
now -= fin - st;
st = fin + 1;
}
asc[ch] = i + 1;
ans = Math.max(ans, now);
}
return ans;
}
}