给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
注意:
字符串长度 和k不会超过
1
0
4
10^4
104。
示例 1:
输入:
s = "ABAB", k = 2
输出:
4
解释:
用两个'A'替换为两个'B',反之亦然。
示例 2:
输入:
s = "AABABBA", k = 1
输出:
4
解释:
将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。
子串 "BBBB" 有最长重复字母, 答案为 4。
解题思路
我们首先可以想到通过滑动窗口来做这个题目。我们首先有一个朴素的想法,就是窗口中的最多重复元素尽可能的多,基于此我们就需要遍历的过程中记录窗口里面出现的最多重复元素的个数。例如
A B A B B
↑ ↑
l r
此时窗口中的最多重复元素是A
,并且它的个数是2
。接着我们看一下移动窗口的过程中,如何去维护它。
我们假设k=1
,那么此时需要替换的元素个数r-l+1-2=1
,我们发现此时等于k
,所以我们需要继续扩大窗口。
A B A B B
↑ ↑
l r
此时B
出现了2
次,那么最多重复元素是B
(虽然B
和A
一样多,但是我们要最近出现的那个),并且r-l+1-2>k
,所以我们需要缩小窗口
A B A B B
↑ ↑
l r
此时r-l+1-2=k
,所以我们扩大窗口。
A B A B B
↑ ↑
l r
我们发现此时的B
出现了3
次,并且r-l+1-3=k
满足条件,我们需要将此时的窗口大小记录下来。
最后代码如下
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
res, n, l, mf = 0, len(s), 0, 0
d = collections.defaultdict(int)
for r, c in enumerate(s):
d[c] += 1
mf = max(mf, d[c])
while r - l + 1 - mf > k:
d[s[l]] -= 1
l += 1
res = max(res, r - l + 1)
return res
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!