给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
注意:字符串长度 和 k 不会超过 104。
示例 1:
输入:s = “ABAB”, k = 2
输出:4
解释:用两个’A’替换为两个’B’,反之亦然。
首先想了一个二分查找的方法,主要就是先确定一下结果的区间,在区间内去查找有没有合适的字符串片段,但是这个方法面对k = 0的时候就完蛋了,主要是因为min_result不会再像上更新了。代码如下
class Solution(object):
def MaxRepeat(self, s):
# 找到字符串s中,最长的重复字母的次数
letter_dict = {}
for letter in s:
if letter in letter_dict.keys():
letter_dict[letter] += 1
else:
letter_dict[letter] = 1
value_sort = list(letter_dict.values())
value_sort.sort()
return value_sort[-1]
def characterReplacement(self, s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
min_len = k
max_len = self.MaxRepeat(s) + k
if max_len > len(s):
max_len = len(s)
result_len = int((min_len + max_len) / 2)
while True:
flag = True
for start in range(len(s) - result_len):
candid = s[start: start + result_len]
min_result = self.MaxRepeat(candid) + k
if min_result > len(s):
min_result = len(s)
if min_result > result_len:
min_len = min_result
flag = False
break
elif min_result == result_len:
min_len = min_result
break
if flag:
max_len = result_len
result_len = int((min_len + max_len) / 2)
if max_len == min_len:
break
return result_len
后来发现用滑动窗口是个好办法,代码如下
class Solution(object):
def characterReplacement(self, s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
MaxRepeat = 0
result = 0
left = 0
letter_dict = {}
for right in range(len(s)):
if s[right] in letter_dict.keys():
letter_dict[s[right]] += 1
else:
letter_dict[s[right]] = 1
MaxRepeat = max(MaxRepeat, letter_dict[s[right]])
while (right - left + 1) - MaxRepeat > k:
letter_dict[s[left]] -= 1
left += 1
result = max(result, (right - left + 1))
return result