思路: 滑动窗口
双指针,快指针在前面扫,不断把字符放到map中,遇到重复的停下,慢指针跳到重复元素第一次出现位置的下一个位置,继续操作。 关键点在于
- i跳到重复数字的下一个后,要记得删除之前的map,否则会对之后的数字造成影响。
2. 优化版
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> map = new HashMap<>();
int i = 0;
int j = 0;
int max = 0;
while (j < s.length()) {
//&&后的条件使得慢指针之前的字符被忽略,从而省去了remove的时间
if (map.containsKey(s.charAt(j)) && map.get(s.charAt(j)) >= i) {
i = map.get(s.charAt(j)) + 1; // 遇到重复字符,收左边界
// j++; no
} else {
map.put(s.charAt(j), j);
max = Math.max(max, j - i + 1);
j++; //未遇到重复字符,扩展右边界
}
}
return max;
}
}
1. 未优化版本
class Solution {
public int lengthOfLongestSubstring(String s) {
//用来存放字符和对应的索引值
Map<Character, Integer> map = new HashMap<>();
int i = 0;//慢指针
int j = 0;//快指针
int max = 0;//最大长度
while (j < s.length()) {
//当快指针遇到重复的字符时,慢指针跳到重复值第一次出现的位置+1
//然后再删掉慢指针位置之前的map,防止对后面造成影响
if (map.containsKey(s.charAt(j))) {
i = map.get(s.charAt(j)) + 1;
for (int k = 0; k < i; k++) {
map.remove(s.charAt(k), k);//这样写会超时
}
} else {//当快指针没有遇到重复的字符,快指针++,计算max
map.put(s.charAt(j), j);
max = Math.max(max, j - i + 1);
j++;
}
}
return max;
}
}