424. 替换后的最长重复字符
给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
注意:字符串长度 和 k 不会超过 104。
示例 1:
输入:s = "ABAB", k = 2
输出:4
解释:用两个'A'替换为两个'B',反之亦然。
示例 2:
输入:s = "AABABBA", k = 1
输出:4
解释:
将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。
子串 "BBBB" 有最长重复字母, 答案为 4。
方法一:滑动窗口
解题思路
「滑动窗口」是一种概念,本题是用 双指针 模拟滑动窗口。
left
指针和right
指针开始都指向0
。right
指针不会停下,每次走一步,直到字符串最后一个字母。left
指针根据情况确定是否需要往前走一步。left
和right
指针会确定一个区间[left, right]
,需要统计区间内每个字母的出现次数和次数最大值maxCount
。目标是要把区间内的其他字母变替换成与maxCount
对应的字母,有替换数量x = right - left - maxCount
。- 当
x <= k
,说明当前区间可以完成替换,此时只需移动right
指针。反之x > k
,说明当前区间不能完成替换,需要right
和left
指针一起移动。 - 最后返回
right - left
。(因为right
一直在移动,而left
是不满足替换条件才移动,所以right - left
一直保持着最大值的距离)
参考代码
public int characterReplacement(String s, int k) {
char[] chars = s.toCharArray();
int len = chars.length;
int[] counts = new int[26];
int maxCount = 0;
int left = 0, right = 0;
while (right < len) {
counts[chars[right] - 'A']++;
maxCount = Math.max(maxCount, counts[chars[right] - 'A']);
right++;
if (right - left - maxCount > k) {
counts[chars[left] - 'A']--;
left++;
}
}
return right - left;
}
执行结果