题目
给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
注意:
字符串长度 和 k 不会超过 104。
输入:
s = “ABAB”, k = 2
输出:
4
解释:
用两个’A’替换为两个’B’,反之亦然。
思路
这道题我第一次做类似的,并没有什么头绪。于是借鉴了评论区的一个solution,大神写的很清楚。图片我就偷一张
这个思路和求字符串中最长连续子串的思路差不多,只是关键的一些判断条件有改变。
当出现较长的连续序列的时候,窗口就应该进行扩展,如果当前还没有超过窗口长度的序列就进行平移。
如果要记录窗口长度最大值,按我自己的思路可能不会对拿变量去统计一些值的最大值,但是大神不一样,使用一个map容器就可以统计win里面的重复字符。
判断window是否需要扩展的依据:只需要判断当前加上新元素之后当前元素在win中的个数是否超过win本身长度。也就是说只有当前win中全是一个字符这时候窗口右侧的字符还是这个字符的情况下,窗口的最大值就增加。
class Solution {
public:
int characterReplacement(string s, int k) {
if(s.size() <= 1) return s.size();
if(s.size() <= k) return s.size();
int left = 0;
int right = 0;
int historyMaxSize = 0;
int *map = new int[26]();
//1.首先做循环遍历
for (char c : s) {
map[c - 'A'] ++;
historyMaxSize = max(historyMaxSize , map[c - 'A']);
//这个地方说明当前没有更长的historyMaxSize + k是指调整过的长度
if(right - left + 1 > historyMaxSize + k) {
//整个窗口进行右移
left ++;
map[s[left] - 1] --;
}
right ++;
}
delete [] m;
//返回的值是s.size() - left
return s.size() - left;
]