想到了用滑动窗口,但是没有想到收缩的条件是什么。在滑动的过程中,不断统计当前窗口中出现最多的字符是哪个,因为显而易见的是我们把其他出现次数没有那么多的字母换成这个最多的,就构成了最长重复字符。
看了解法之后发现是和这个 k 比较即可。因为当其他字符的数量多于 k 时,说明我们窗口过大,有一些字符即便我们把所有替换次数用光,也不能保证窗口内的是重复的了。这时候收缩即可。
还有一个要注意的就是这个滑动过程中,某些状态下划出的串其实是不合法的,但这并不重要,因为如果遇到更长的情况它自然会扩张。
代码如下:
const characterReplacement = function(s, k) {
// a map for tracking the occurrences of numbers
const visited = {};
// store the largest occurrences times of current window
let largestCount = 0;
let l = 0;
let r = 0;
while (r < s.length) {
const curr = s[r];
visited[curr] = visited[curr] ? visited[curr] + 1 : 1;
// update the largest
if (visited[curr] > largestCount) {
largestCount = visited[curr];
}
// if the length of all other chars is greater than k
if (r - l + 1 - largestCount > k) {
// reduce the count of the left most char
visited[s[l]]--;
// shrink the window from the left
l++;
}
r++;
}
// the size of the window is the answer
return r - l;
};