3. Longest Substring Without Repeating Characters
340. Longest Substring with At Most K Distinct Characters
这两道都是经典题目,思路是sliding window + hashMap/HashSet.
具体3用HashSet, 340用HashMap。
题目不难,但不容易一次写对。我在面试的时候就忘了一点。
下面分析一下这两道题容易错的地方。
1。 分析各种情况时,往往忘了在某个case把字母放入HashSet, 光记得删了。
2。算长度时slow, fast pointer忘了+1 了。
3。 slow, fast pointer忘了移动了。。 为了避免出错,最好把fast++放在循环的最后,但一开写while loop就写上。(用continue时要小心)
4。 Set, HashMap这些不要直接叫set, map的,要取有意义的名字,不然容易成为挂点
public int lengthOfLongestSubstringKDistinct(String s, int k) {
Map<Character, Integer> visitedTimes = new HashMap<>();
int ans = 0;
int slow = 0, fast = 0;
if (k == 0) return 0;
while (fast < s.length()) {
char ch = s.charAt(fast);
if (visitedTimes.containsKey(ch)) {
visitedTimes.put(ch, visitedTimes.get(ch) + 1);
} else if (visitedTimes.size() < k) {
visitedTimes.put(ch, 1);
} else {
while (slow < fast) {
char ch2 = s.charAt(slow++);
if (visitedTimes.get(ch2) == 1) {
visitedTimes.remove(ch2);
break;
} else {
visitedTimes.put(ch2, visitedTimes.get(ch2) - 1);
}
}
visitedTimes.put(ch, 1); //别忘了加这个。
}
ans = Math.max(fast - slow + 1, ans);
fast++; //一开写while 就写在这里,但要注意如果某次用了continue语句要++
}
return ans;
}
LC 3的代码
public int lengthOfLongestSubstring(String s) {
Set<Character> visitedChars = new HashSet<>();
int slow = 0, fast = 0;
int ans = 0;
while (fast < s.length()) {
if (visitedChars.add(s.charAt(fast))) {
fast++;
ans = Math.max(ans, fast - slow);
} else {
while (s.charAt(slow) != s.charAt(fast)) {
visitedChars.remove(s.charAt(slow++));
}
slow++;
fast++;
}
}
return ans;
}