替换后的最长重复字符
替换后的最长重复字符
给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换k
次。在执行上述操作后,找到包含重复字母的最长子串的长度。
注意:字符串长度 和k
不会超过104
。
示例#
输入:s = "ABAB", k = 2
输出:4
解释:用两个'A'替换为两个'B',反之亦然。
输入:s = "AABABBA", k = 1
输出:4
解释:
将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。
子串 "BBBB" 有最长重复字母, 答案为 4。
题解#
/**
* @param {string} s
* @param {number} k
* @return {number}
*/
var characterReplacement = function(s, k) {
const n = s.length;
const chars = new Array(26).fill(0);
let maxn = 0, left = 0, right = 0;
for(; right<n ; ++right){
// 右指针的 ASCII - 26
const indexRight = s[right].charCodeAt() - "A".charCodeAt();
chars[indexRight]++;
// 取数量最大的值 维护maxn一直是最大值
// 窗口长度只能增大或者不变 left指针只移动了0/1次
// 这样做的意义是我们求的是最长,如果找不到更长的维持长度不变返回结果不受影响
maxn = Math.max(maxn, chars[indexRight]);
// 窗口长度len=right-left+1
if (right - left + 1 - maxn > k) {
// 左指针右移则需要将中间的滑动窗口该点的统计数量-1
chars[s[left].charCodeAt() - "A".charCodeAt()]--;
left++;
}
}
// 此时长度应该是 (right-1)-left+1 === right-left
return right - left;
};
思路#
基本对于连续的数据的操作都可以考虑使用双指针维护一个滑动窗口去做,当然也有可能采用动态规划的做法,本题使用双指针维护滑动窗口,这个题目官方的思路比较好,就直接以官方的思路做个解释,我们可以枚举字符串中的每一个位置作为右端点,然后找到其最远的左端点的位置,满足该区间内除了出现次数最多的那一类字符之外,剩余的字符(即非最长重复字符)数量不超过k
个,这样我们可以想到使用双指针维护这些区间,每次右指针右移,如果区间仍然满足条件,那么左指针不移动,否则左指针至多右移一格,保证区间长度不减小,这样做的意义是我们求的是最长,如果找不到更长的维持长度不变返回结果不受影响,当我们右指针移动到尽头,左右指针对应的区间的长度必然对应一个长度最大的符合条件的区间。
我们以示例的ABAB 2
为例来模拟一遍这个过程,过程为每次循环结束的位置,注意第四次循环结束后right===n
。
left:0 right:1 window:AB len:2
left:0 right:2 window:ABA len:3
left:0 right:3 window:ABAB len:4
left:0 right:4 window:ABAB len:5
首先我们定义n
为字符串长度,定义数组并初始化值为0
用以记录各个字符的数量,之后定义maxn
用以记录出现次数最多的值,以及left
与right
两个指针,之后定义循环,首先取得right
指针的ASCII-26
值,将记录数组中这个字符的数量++
,之后使用Math.max
取得当前字符数量出现的最大值,注意此时由于我们是逐个增加记录数组中的值,并且左指针右移时将字符的值--
,所以我们只需要取得之前的最大值与当前处理的字符的数组最大值即可,之后比较窗口的长度与k
的大小,如果长度比k
大则将左指针指向的字符在数组中的统计值--
,之后左指针右移,最后返回窗口长度right - left
即可,实际上是因为循环的最后right
多出1
所以是(right-1)-left+1 === right-left
。
每日一题#
https://github.com/WindrunnerMax/EveryDay
参考#
https://leetcode-cn.com/problems/longest-repeating-character-replacement/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理