1. 题目
2. 思路
考虑使用双指针,如果字符没有重复,则右指针继续后移;如果字符重复了,把左指针一直右移,一直到字符不重复为止,右移的时候需要把遍历到的都移除。
3. 代码
3.1 第一版答案
第一版答案没有通过下面的case:
""
class Solution {
public static int lengthOfLongestSubstring(String s) {
int i = 0, j = 0;
int lMax = 0, rMax = 0;
Set<Character> set = new HashSet<>();
while (j < s.length()) {
if (set.contains(s.charAt(j))) {
if (j - 1 - i > rMax - lMax) {
rMax = j - 1;
lMax = i;
}
while (s.charAt(j) != s.charAt(i)) {
i++;
}
i++;
j++;
} else {
set.add(s.charAt(j));
j++;
}
}
return rMax - lMax + 1;
}
}
分析:
这段代码有两个问题:
- 计算最大长度的地方应该是在没有出现重复的时候
- 代码中在字符出现重复的时候,把右指针进行了右移,导致右指针所在字符这个长度没有被计算
3.2 版本2
class Solution {
public static int lengthOfLongestSubstring(String s) {
int i = 0, j = 0;
int max = 0;
Set<Character> set = new HashSet<>();
while (j < s.length()) {
if (set.contains(s.charAt(j))) {
while (s.charAt(j) != s.charAt(i)) {
i++;
}
i++;
} else {
if (j - i + 1 > max) {
max = j - i + 1;
}
set.add(s.charAt(j));
}
j++;
}
return max;
}
}
这个版本还是无法通过
"tmmzuxt"这个case。
分析:
因为在左指针右移的时候没有将遍历到的字符移除set。
3.3 版本3
class Solution {
public static int lengthOfLongestSubstring(String s) {
int i = 0, j = 0;
int max = 0;
Set<Character> set = new HashSet<>();
while (j < s.length()) {
if (set.contains(s.charAt(j))) {
while (s.charAt(j) != s.charAt(i)) {
set.remove(s.charAt(i));
i++;
}
set.remove(s.charAt(i));
i++;
} else {
if (j - i + 1 > max) {
max = j - i + 1;
}
set.add(s.charAt(j));
j++;
}
}
return max;
}
}