问题描述
有一个由大写字母组成的字符串长度为n,现在可以对字符串中的字符进行修改:
每次允许将某个位置的字符修改为任意字符,比如说将字符串ABC第1个字符A改为B,则字符串变成BBC;
这个操作最多可以执行k次,现在想知道修改之后,字符串中由最多两种字母组成的子串最大长度。
输入格式
每个样例有两行;
第一行是整数 n, k,n 表示字符串长度,k 表示可以修改的最多次数;(3≤n≤2000, 1≤k≤100)
第二行是长度为 n 的字符串;
输出格式
每个样例一行,输出修改之后,由最多两种字母组成的子串最大长度;
输入样例1
6 1
ABCBAD
输出样例1
5
输入样例2
5 1
AEABD
输出样例2
4
数据范围
(3≤n≤2000, 1≤k≤100)
提示:
每日一练: 字符替换 这个问题要求在一个字符串中找到由最多两种不同字符组成的最长子串,允许我们进行最多 k 次字符替换操作。我们可以通过滑动窗口的方法解决这个问题。
function maxLenWithTwoChars(n, k, s) {
// 定义一个辅助函数,用来计算包含最多两种字符的最长子串长度
function getMaxLenWithTwoChars(char1, char2) {
let left = 0; // 滑动窗口的左指针
let count1 = 0; // 记录字符 char1 在窗口内的出现次数
let count2 = 0; // 记录字符 char2 在窗口内的出现次数
let replaceCount = 0; // 记录需要替换的字符个数
let maxLen = 0; // 记录最大子串长度
// 右指针遍历字符串
for (let right = 0; right < n; right++) {
// 判断右指针指向的字符是否是 char1 或 char2
if (s[right] === char1) {
count1++;
} else if (s[right] === char2) {
count2++;
} else {
replaceCount++;
}
// 如果替换的字符超过 k 个,则缩小窗口
while (replaceCount > k) {
if (s[left] === char1) {
count1--;
} else if (s[left] === char2) {
count2--;
} else {
replaceCount--;
}
left++; // 缩小窗口,左指针右移
}
// 更新最大长度
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen; // 返回该字符对的最大子串长度
}
let maxResult = 0; // 最终结果最大长度
// 遍历所有可能的两两字符组合 (A-Z)
for (let i = 0; i < 26; i++) {
for (let j = i; j < 26; j++) {
// 获取字符组合,char1 和 char2 是 'A' 到 'Z' 之间的字符
let char1 = String.fromCharCode(65 + i);
let char2 = String.fromCharCode(65 + j);
// 计算当前字符组合的最大长度
maxResult = Math.max(maxResult, getMaxLenWithTwoChars(char1, char2));
}
}
return maxResult; // 返回最终的最大长度结果
}
function main() {
// Add your test cases here
console.log(maxLenWithTwoChars(6, 1, "ABCBAD") === 5);
console.log(maxLenWithTwoChars(5, 1, "AEABD") === 4);
}
main();