题目说明
题解
这个题目找对方法之后解起来应该说是很简单的,但是一开始自己掉进了贪心的坑里,想着通过找到最长的连续重复串,在其左/右进行替换即可,利用递归完成贪心算法,但是后来仔细琢磨了一下发现事情并没有这么简单(元芳,你怎么看…)。
最直接的一种情况[‘AAAAABCCCDCCCC’, k = 1],在该测试例下,替换掉’D显然比替换’B’获得的结果更大,因此贪心算法毫无用武之地。后来只好主动放弃,看了不少网上的题解,最受欢迎的解法还是使用滑动窗口(Sliding Windows),且滑窗法似乎是求解字符串类问题的常用思路。
具体的求解思路如下:
- 初始化滑动窗口,起始窗口宽度为0,定义start和end指针。
- 创建大小为26的一维数组,这是因为题目中指出所有字符均为26位大写字母中的一个,因此我们用一个数组来记录每个字符在当前窗口中出现的次数,每次找到出现次数最多的并记录器出现次数为maxCount。
- 不断移动窗口,移动的原则是:
- 假如窗口内出现次数最多的字符与
k
相加小于当前窗口的大小(说明当前的滑窗大小过大),那么将start指针右移,随后end指针右移;若不然,只有end指针右移。
下面给出具体的python实现代码
def characterReplacement(self, s:str, k:int) -> int :
if s.__len__() == 0:
return 0
# 滑窗左边界
start = 0
# 滑窗右边界
end = 0
# 滑窗滑过的部分中出现次数最多的字符
maxCount = 0
# 定义数组保存单个字符出现的次数
charNum = [0] * 26
# 主循环
while end < len(s):
# 对应位置的字符数目+1
charNum[ord(s[end]) - ord('A')] += 1
# 获取最大字符数,比较当前位置的字符数与先前最大值的大小,
# 取二者较大的一个
maxCount = max(maxCount, charNum[ord(s[end]) - ord('A')])
# 假如maxCount + k比窗口宽度窄,说明当前的宽度已经是最大宽度
# 此时同时右移start和end
# 此处需要注意,我们最终所需要的结果就是滑窗的宽度,很重要!
if maxCount + k < end - start + 1:
charNum[ord(s[start]) - ord('A')] -= 1
start += 1
end += 1
return end - start
可以看到,代码之简洁令人瞠目结舌,核心部分在while循环内部。
这里附送一个使用滑窗求取字符串内最大连续重复字符个数的python程序(自己写的,不一定完全是bugless),大家有问题的可以评论区讨论。
def findLongest(s:str) -> tuple:
start = 0
end = 0
while end < len(s):
if s[start] == s[end]:
end += 1
if end >= len(s):
break
if start < end and s[start] != s[end]:
start += 1
end += 1
return end - start