题目
给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符,并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。
在执行上述操作后,返回包含相同字母的最长子字符串的长度。
示例 1:
输入:s = “ABAB”, k = 2
输出:4
解释:用两个’A’替换为两个’B’,反之亦然。示例 2:
输入:s = “AABABBA”, k = 1
输出:4
解释:
将中间的一个’A’替换为’B’,字符串变为 “AABBBBA”。
子串 “BBBB” 有最长重复字母, 答案为 4。提示:
1 <= s.length <= 10^5
s 仅由大写英文字母组成
0 <= k <= s.length来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-repeating-character-replacement
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
滑窗思路,统计滑窗内最高频次的字符,最多允许有k个不同的字符,即需要满足len(滑窗)-maxCnt<=k,其中maxCnt为滑窗内频次最高的字符次数。
因为字符串全部是大写字母,因此,使用一个数组统计字符频次,并实时更新maxCnt。剩下的就是常规的滑窗写法。
需要注意的是,当滑窗左边界收缩时,mCnt的定义不用维护,原因「官解」说的很清楚了,确实有点不太好理解,这里就不说明了。
代码
class Solution {
public int characterReplacement(String s, int k) {
int n = s.length();
int[] cnt = new int[26];
int left = 0;
int right = 0;
int ans = 0;
int mCnt = 0;
while (right < n) {
cnt[s.charAt(right) - 'A']++;
mCnt = Math.max(mCnt, cnt[s.charAt(right) - 'A']);
while (right - left + 1 - mCnt > k) {
cnt[s.charAt(left) - 'A']--;
left++;
}
ans = Math.max(ans, right - left + 1);
right++;
}
return ans;
}
}