当前位置: 首页 > news >正文

LeetCode 424 - 替换后的最长重复字符

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码解析
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

这道题《LeetCode 424. 替换后的最长重复字符》属于典型的滑动窗口题目,同时也考验我们对字符串区间内特征值的理解。题目要求在最多替换 k 次字符的前提下,找到最长的一段“重复字符子串”。
虽然描述看起来有点拗口,但它本质上是在问:
在一个窗口中,如果我们把最多 k 个字符替换成某一个字符,窗口能达到的最大长度是多少?
这个问题在日志分析、字符串纠错、甚至简单压缩算法中都有类似逻辑,实际应用还挺广的。

描述

给定一个由大写英文字母组成的字符串 s,我们可以最多执行 k 次替换操作,每次可将任意字符替换成任意大写英文字母。目标是得到一个最长的子串,这个子串的所有字符最终都一样。

举个例子:
s = "ABAB", k = 2,我们可以把两个 A 都改成 B,也可以反过来,把两个 B 改成 A。
最长的重复子串长度是 4。

再比如:
s = "AABABBA", k = 1,通过把中间一个 A 改成 B,我们能得到最长重复子串 BBBB,长度是 4。

这个题的关键点不是“具体替换成什么”,而是“窗口中最大相同字母数量和窗口长度的关系”。

题解答案

最佳做法是使用滑动窗口,并且窗口是不断向右扩张的,同时控制窗口是否可行。

核心判断条件是:
窗口长度 - 窗口内出现次数最多的字符数量 ≤ k
只要满足这个条件,窗口就是合法的,因为我们最多只需要替换 k 个字符,就能把整个窗口变成一种字符。

这里有一个非常关键的技巧:
窗口内“出现次数最多的字符数量”不需要准确更新,也不需要在窗口缩小时同步减少。
只要保持它是当前出现过的最大值即可(这个值是单调不减的)。
实际验证时完全成立,会让整个算法线性化。

题解代码分析

下面是完整可运行的 Swift 版本:

import Foundationclass Solution {func characterReplacement(_ s: String, _ k: Int) -> Int {let chars = Array(s)var freq = [Int](repeating: 0, count: 26)var left = 0var maxCount = 0   // 窗口内出现最多的字符次数var result = 0for right in 0..<chars.count {let index = Int(chars[right].asciiValue! - Character("A").asciiValue!)freq[index] += 1maxCount = max(maxCount, freq[index])// 如果窗口不合法,则收缩while (right - left + 1) - maxCount > k {let leftIndex = Int(chars[left].asciiValue! - Character("A").asciiValue!)freq[leftIndex] -= 1left += 1}result = max(result, right - left + 1)}return result}
}// Demo 测试
let s = Solution()
print("测试1:", s.characterReplacement("ABAB", 2))     // 4
print("测试2:", s.characterReplacement("AABABBA", 1))  // 4

代码解析

整个逻辑分成几块:

  1. 字符数组
    将字符串转成数组能提升访问效率,同时方便根据 ASCII 做计数。

  2. 频率数组 freq
    用 26 长度的数组存每个字母的出现次数。
    因为只有大写字母,不需要用哈希表。

  3. 滑动窗口左右边界
    right 一直向右移动,而 left 在窗口非法时向右缩小窗口。

  4. maxCount 的意义

    • 在窗口内出现最多的字符出现了 maxCount 次
    • 如果窗口长度比 maxCount 大太多,就说明需要替换的字符数太多
    • 超过 k 时必须移动 left

    注意:maxCount 不会减少,这个行为是故意的,它保证 O(n) 运行。

  5. 每次更新 result
    当前窗口长度就是一个可能的答案。

整体代码虽然不算短,但结构非常稳健,非常适用于大规模字符串处理。

示例测试及结果

测试 1:

输入: s = "ABAB", k = 2
输出: 4

解释:
把两个 A 换成 B,或反过来,把两个 B 换成 A,都能得到 “AAAA” 或 “BBBB”。

测试 2:

输入: s = "AABABBA", k = 1
输出: 4

执行 Demo 后输出:

测试1: 4
测试2: 4

可以看到结果完全一致,这也验证了滑动窗口的正确性。

时间复杂度

O(n)
整个字符串只被右指针遍历一遍,左指针最多走 n 次,没有回头的操作。
频率计算与判断操作都是 O(1)。

对于长度 10⁵ 的字符串,这个性能非常友好。

空间复杂度

O(1)
频率数组固定 26 个元素,额外变量常量级,空间不随输入规模变化。

总结

这道题乍一看有点像动态规划或者暴力枚举,但真正的最优解其实是滑动窗口。
关键思想在于判断窗口可行性的条件:窗口长度与最大频率的关系。
理解了 “窗口长度 - 最大频率 ≤ k” 这个公式,就等于是掌握了整道题。

实际开发中,如果你需要做:

  • 日志文本清洗
  • 文本纠错系统
  • 简单压缩编码优化
  • 某类统计窗口中连续字符结构的业务

这一类问题都能用到类似的窗口思想。

http://www.dtcms.com/a/610567.html

相关文章:

  • 数据结构--9:反射、枚举以及lambda表达式(了解即可)
  • Chartjs画二氧化碳浓度曲线
  • ts语法ts语法ts语法
  • 网站打开慢原因wordpress多站点 用户同步
  • 游戏被IP限制多开,如何在同一网络下用不同IP多开游戏?
  • MiniCPM-o 2.6 小参数挑战巨头 多模态直播流直达手机
  • 网站创建免费用户可信赖的手机网站设计
  • C++20--- concept 关键字 为模板参数提供了编译期可验证的约束机制
  • 厦门市住宅建设办公室网站php开发工具 wordpress
  • 用dw做一个个人网站营销网站建设优化
  • Catia中 零件 部件 产品
  • 自动化技术演进:从工具执行到认知决策,AI如何重塑业务自动化?
  • Springboot美食私厨在线预约管理系统5zf46km2(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 网站建设公司十大id导入不了wordpress
  • php网站开发权限管理wordpress随机幻灯片
  • 团购小程序区域化运营:多门店管理、配送范围设置与本地化活动开发
  • 企业网站备案时间荆州seo优化
  • 可以做积分的网站辽宁网站建设墨子
  • c语言编译环境和运行环境 | 深入理解C语言开发环境的构成与作用
  • 做违法网站犯法吗查建设标准网站
  • Tpri-Datavue前端插件系统文档
  • jmeter发送SOAP请求对WebService接口进行测试
  • 哪个网站做任务可以赚钱网站后台的数据库怎么做
  • 自建开发工具IDE(二)文件托拽读取——东方仙盟炼气期
  • 青岛 网站科技公司wordpress商品资源
  • 数据结构 11 图
  • 通过Golang订阅binlog实现轻量级的增量日志解析,并解决缓存不一致的开源库cacheflow
  • 写作网站哪个名声好互联网运营模式有哪几种
  • 磁共振成像原理(理论)32:分辨率限制 (Resolution Limitations)
  • StringRedisTemplate的用法详解