题目地址:
https://leetcode.com/problems/longest-repeating-character-replacement/description/
给定一个长 n n n字符串 s s s,其只含大写字母。再给定一个非负整数 k k k,允许将 s s s中不超过 k k k个字母换成别的大写字母,问能使得其某个单一字母组成的子串最长的调整策略下,那个单一字母子串的最长长度。
我们可以枚举这个最长单一字母子串的字母 c c c是哪个,接着枚举这个最长单一字符子串的右边界,当右边界为 i i i的时候,其左边界 j j j应当是最左边的使得窗口内的 c c c出现次数大于等于窗口长度 i − j + 1 − k i-j+1-k i−j+1−k,这样的话将除了 c c c之外的其余字母都调整掉即得长度 i − j + 1 i-j+1 i−j+1,可以用这个结果更新答案。可以证明,左端点是不会回退的,如果回退,那么对于回退后的左边界和新的右边界(即 i + 1 i+1 i+1)有一个调整策略,我们将这个调整策略应用到右边界是 i i i的情形下,那么这个回退的左边界更优,这就矛盾了。代码如下:
class Solution {
public:
int characterReplacement(string s, int k) {
int res = 0;
for (char ch = 'A'; ch <= 'Z'; ch++)
for (int i = 0, j = 0, cnt = 0; i < s.size(); i++) {
if (s[i] == ch) cnt++;
while (i - j + 1 - cnt > k)
if (s[j++] == ch) cnt--;
res = max(res, i - j + 1);
}
return res;
}
};
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。