这是一道经典的two pointer的题目。
这里面先用了一个map来统计哪些字母出现过并出现了几次。
然后神奇的地方是用了一个变量lettersToMatch来追踪match 过程。
为什么这里可以用双指针? 假设左右指针之间是一个满足条件的字符串,当右指针右移一位,左指针为了保持题目中的条件,要么也右移,要么不动,不需要左移。所以可以用双指针。
当右移了一个字母时,我们加了一个新的字母c, 我要看一下现在还缺不缺c:如果缺c, 则lettersToMatch--; 如果不缺c, lettersToMatch不变。如果map里面本来就没有c, 则直接跳下一个。把map里面c对应的count--;
当letterToMatch为0的时候,要主动移动左指针,看在仍然满足条件的情况下,左指针能走多远。这时更新结果。
代码如下。
public String minWindow(String s, String t) {
//count of T
int lettersToMatch = 0;
Map<Character, Integer> countMap = new HashMap<>();
for (char c : t.toCharArray()) {
countMap.put(c, countMap.getOrDefault(c, 0) + 1);
lettersToMatch++;
}
int len = Integer.MAX_VALUE;
String ans = "";
// two pointer
int l = 0, r = 0;
// slow, fast and update
while (r < s.length()) {
char c = s.charAt(r);
//add charAt(r)
if (countMap.get(c) == null) {
r++;
continue;
} else {
countMap.put(c, countMap.get(c) - 1);
if (countMap.get(c) >= 0) lettersToMatch--;
}
// // if lettersToMathc == 0, move l to whatever it can
if (lettersToMatch == 0) {
while (l <= r) {
char cl = s.charAt(l);
if (countMap.get(cl) != null) {
if (countMap.get(cl) < 0) {
countMap.put(cl, countMap.get(cl) + 1);
} else break;
}
l++;
}
if (r - l + 1 < len) {
len = r - l + 1;
ans = s.substring(l, r + 1);
}
}
r++;
}
return ans;
}
网友评论