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

leetcode2379:得到K个黑块的最少涂色次数(定长滑动窗口)

文章目录

  • 一、 题目描述
  • 二、 核心思路:问题转换 + 定长滑动窗口
  • 三、 代码实现与深度解析
  • 四、 关键点与复杂度分析

LeetCode2379. 得到 K 个黑块的最少涂色次数,【难度:简单;通过率:64.1%】,这道题的巧妙之处在于,它将一个看似需要“涂色操作”的问题,通过思维转换,变成了一个我们非常熟悉的 “计数” 问题

一、 题目描述

给你一个长度为 n,下标从 0 开始的字符串 blocksblocks[i] 要么是 'W' 要么是 'B',分别表示白色和黑色。同时给你一个整数 k,表示你想要得到的连续黑色块的数目

每一次操作中,你可以选择一个白色块将它涂成黑色

请你返回至少出现一次连续 k 个黑色块的 最少 操作次数

示例:

示例 1:

输入:blocks = "WBBWWBBWBW", k = 7
输出:3解释:
一种得到 7 个连续黑色块的方法是把第 0 ,3 和 4 个块涂成黑色
得到 blocks = "BBBBBBBWBW"
可以证明无法用少于 3 次操作得到 7 个连续的黑块
所以我们返回 3 

示例 2:

输入:blocks = "WBWBBBW", k = 2
输出:0解释:
不需要任何操作,因为已经有 2 个连续的黑块
所以我们返回 0

二、 核心思路:问题转换 + 定长滑动窗口

初看题目,可能会想到模拟涂色。但仔细思考后会发现 要使一个长度为 k 的子串全部变为黑色,需要操作的次数恰好等于这个子串中白色块 ‘W’ 的数量

因此,题目就转换成了:在字符串 blocks 中,找到所有长度为 k 的子串,哪一个子串包含的 ‘W’ 字符数量最少?

触发关键词: “子串”,可以尝试尝试滑动窗口来解决,尝试分析一个思路:

  1. 初始化窗口:首先,我们创建一个大小为 k 的窗口,覆盖字符串的前 k 个字符。我们计算出这个初始窗口中 ‘W’ 的数量,并将其作为初始的最小操作次数 ans
  2. 滑动窗口:然后,让窗口向右逐格滑动。每次滑动,我们都高效地更新窗口内 ‘W’ 的数量:
    • 如果离开窗口的左侧字符是 ‘W’,则计数减 1
    • 如果进入窗口的右侧新字符是 ‘W’,则计数加 1
  3. 更新结果:每次滑动后,我们都将当前窗口的 ‘W’ 数量与已知的最小值 ans进行比较,并随时更新 ans
  4. 最终结果:遍历完整个字符串后,ans 就是所有长度为 k 的子串中 ‘W’ 的最少数量,即题目的答案

三、 代码实现与深度解析

class Solution {public int minimumRecolors(String blocks, int k) {// 转为字符数组,提高效率char[] arr = blocks.toCharArray();// cnt: 记录当前窗口内白色 ('W') 块的数量// l: 窗口的左边界索引// ans: 记录到目前为止,所有窗口中白色块的最小数量int cnt = 0, l = 0, ans; // 步骤 1: 初始化第一个窗口(从索引 0 到 k-1)// 遍历前 k 个字符,计算初始窗口内的白色块数量for (int i = 0; i < k; i++) {// 如果当前字符是 'W',则 cnt 加 1cnt = arr[i] == 'W' ? cnt + 1 : cnt;}// 将第一个窗口的白色块数量作为初始的最小操作次数ans = cnt;// 步骤 2: 滑动窗口遍历剩余的字符串// r: 窗口的右边界索引,从 k 开始,直到数组末尾// 每次循环,窗口向右滑动一格for (int r = k; r < arr.length; r++) {// 2.1 处理滑出窗口的左侧字符 (arr[l])// 如果 arr[l] 是 'W',说明一个白色块离开了窗口,cnt 减 1// l++ 使左边界向右移动一格,为下一次循环做准备cnt = arr[l++] == 'W' ? cnt - 1 : cnt;// 2.2 处理滑入窗口的右侧字符 (arr[r])// 如果 arr[r] 是 'W',说明一个白色块进入了窗口,cnt 加 1cnt = arr[r] == 'W' ? cnt + 1 : cnt;// 2.3 更新最小操作次数// 每次窗口滑动完成后,当前窗口的白色块数量 (cnt) 可能是一个新的最小值// 将其与之前记录的 ans 比较,取较小值ans = Math.min(ans, cnt);}// 步骤 3: 返回最终结果// 循环结束后,ans 就存储了所有长度为 k 的子串中白色块的最少数量,// 这也正是题目所求的最少操作次数return ans;}
}

提交结果:
在这里插入图片描述

四、 关键点与复杂度分析

  • 思维转换:本题的关键在于将“最少操作次数”等价于“定长子串中最少的 ‘W’ 数量”
  • 定长滑动窗口:这是解决此类问题的标准模板,通过 O(1) 的更新操作,避免了对每个子串的重复计算
  • 时间复杂度O(N) 其中 N 是字符串 blocks 的长度。我们只需要遍历一次字符串
  • 空间复杂度O(1) 或 O(N) 如果将 toCharArray() 的开销计算在内,则为 O(N);如果不计,则只使用了常数个额外变量,为 O(1)
http://www.dtcms.com/a/324256.html

相关文章:

  • 2.变量和常量
  • Go 工具链环境变量实战:从“command not found”到工具全局可用的全流程复盘
  • 【数据结构入门】栈和队列的OJ题
  • 二维前缀和问题
  • MySQL面试题及详细答案 155道(041-060)
  • 构建第三方软件仓库
  • 数据类型取值范围
  • String AOP、事务、缓存
  • 【18】OpenCV C++实战篇——【项目实战】OpenCV C++ 精准定位“十字刻度尺”中心坐标,过滤图片中的干扰,精准获取十字交点坐标
  • 力扣559:N叉树的最大深度
  • XGBoost算法在机器学习中的实现
  • C语言:指针(2)
  • Gin vs Beego vs Echo:三大主流 Go Web 框架深度对比
  • 前端开发中的常见问题与实战解决方案​
  • JS数组排序算法
  • scanpy单细胞转录组python教程(三):单样本数据分析之数据标准化、特征选择、细胞周期计算、回归等
  • 2025.8.10总结
  • 学生成绩管理系统的 SQL 表设计与多表查询实战
  • 部署一个免费开源的博客系统
  • 库的制作和原理
  • 双亲委派机制是什么?
  • 大模型工具集成四层架构:识别、协议、执行与实现
  • reinterpret_cast and static cast
  • Lua的数组、迭代器、table、模块
  • Elasticsearch 搜索模板(Search Templates)把“可配置查询”装进 Mustache
  • 从MySQL到大数据平台:基于Spark的离线分析实战指南
  • 重学React(四):状态管理二
  • Spark执行计划与UI分析
  • 【软考中级网络工程师】知识点之 DCC 深度剖析
  • 系统架构设计师备考之架构设计高级知识