字符替换与最长子串问题
一、问题描述
给定一个由大写字母组成的字符串,长度为 n。我们可以最多进行 k 次字符替换操作,每次可以将字符串中的一个字符修改为任意大写字母。小R想知道,通过最多 k 次修改后,字符串中由最多两种不同字母组成的最长连续子串的长度是多少。
二、思路解析
这个问题的核心在于:
如何通过最多 k 次修改,使得字符串中的最大子串由不超过两种字母组成。我们可以通过滑动窗口的思想来高效地解决这个问题。具体步骤如下:
-
滑动窗口:
我们可以定义一个滑动窗口,窗口内的字符最多包含两种不同的字母。 当窗口内的字符超过两种时,缩小窗口(通过移动窗口左边界),以保持窗口内只有两种字母。
-
字符替换计数:
每当窗口内的字符超过两种时,我们需要通过字符替换来减少字符种类。每次替换会消耗一个修改次数。如果修改次数超过
k,就需要调整窗口大小,保持替换次数不超过k。 -
最大长度更新:
在滑动窗口过程中,始终记录满足条件的最大子串长度。
-
枚举两种字母的组合:
我们需要尝试所有可能的字符组合(最多两种字符),然后找出其中最长的子串。
三、解题步骤
滑动窗口算法:通过两个指针 left 和 right,构造一个滑动窗口。窗口内的字符最多只能包含两种字符。
字符替换计数:统计窗口内不属于这两种字符的其他字符数量,并通过移动 left 指针来控制替换次数不超过 k。
计算并更新最大长度:每次窗口满足条件时,更新最大子串的长度。
四、复杂度分析
1.时间复杂度:O(262∗n)O(26^2 * n)O(262∗n)。
需要枚举所有可能的字符对(最多 26 种字母的两两组合),对于每一对字符,使用滑动窗口计算最大子串的长度。对于每对字符组合,滑动窗口的时间复杂度是 O(n)。因此,总时间复杂度是 O(262∗n)O(26^2 * n)O(262∗n)。
2.空间复杂度:O(n)O(n)O(n)。
主要的空间消耗是存储滑动窗口内的字符和一些辅助变量。
五、代码展示
def solution(n, k, inp):
辅助函数:获取由最多两种字母组成的最长子串的长度
def get_max_len(c1, c2):
left = 0
changes = 0
max_len = 0 # 右指针滑动窗口
for right in range(n):
# 如果当前字符既不是 c1 也不是 c2,说明需要替换
if inp[right] != c1 and inp[right] != c2:
changes += 1 # 如果修改次数超过 k,缩小窗口
while changes > k:
if inp[left] != c1 and inp[left] != c2:
changes -= 1 left += 1
# 更新最大子串长度
max_len = max(max_len, right - left + 1)
return max_len # 尝试所有字符的两两组合,找到最长的子串
result = 0 for i in range(26): for j in range(i, 26): c1 = chr(ord('A') + i) c2 = chr(ord('A') + j) result = max(result, get_max_len(c1, c2)) return result