2379.得到K个黑块的最少涂色次数

目录

题目描述

示例1:

示例2:

提示:

解题思路

滑动窗口法

概念

应用场景及特点:

思路

流程展示

代码

复杂度分析


题目描述

给你一个长度为 n 下标从 0 开始的字符串 blocksblocks[i] 要么是 'W' 要么是 'B' ,表示第 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 。

提示:

  • n == blocks.length
  • 1 <= n <= 100
  • blocks[i] 要么是 'W' ,要么是 'B' 。
  • 1 <= k <= n

解题思路

滑动窗口法

概念

滑动窗口是一个在序列上移动的区间,通常由左右两个指针来界定这个区间的范围。通过移动指针来改变窗口的大小和位置,在窗口移动的过程中,根据问题的需求进行特定的计算和处理。

应用场景及特点

  1. 子数组 / 子串问题
  • 通常有两个指针,一个指向窗口的左端,一个指向窗口的右端。根据问题的具体要求,以特定的方式移动指针。
  • 例如,在寻找满足特定条件的最小子数组时,可能会先扩大窗口直到满足条件,然后再缩小窗口以找到最小的满足条件的窗口。
  1. 指针移动规则
  • 相比于暴力枚举所有可能的子数组 / 子串,滑动窗口法通常能够在更短的时间内找到解。因为它利用了子数组 / 子串的连续性和窗口的滑动特性,避免了重复计算。
  1. 高效性
  • 当需要在一个序列中找到满足特定条件的连续子数组或子串时,滑动窗口非常适用。例如,寻找和为特定值的连续子数组、含有特定字符的最长子串等。
  • 窗口的大小通常是动态变化的,根据问题的条件进行调整。

思路

  1. 初始化
  • 首先计算初始窗口(前k个字符)中白色块的数量,这个数量就是把这部分变成连续k个黑色块所需的最少操作次数。记为cnt_w(初始窗口中白色块的数量)和ans(最少操作次数)。
  1. 滑动窗口遍历
  • 使用滑动窗口遍历整个字符串。窗口大小为k
  • 每次窗口向右移动一个字符,新进入窗口的字符记为in_,离开窗口的字符记为out
  • 如果新进入窗口的字符是'W',则将cnt_w加 1,表示需要多一次操作把这个白色块变成黑色。
  • 如果离开窗口的字符是'W',则将cnt_w减 1,表示这个白色块不再在窗口内,之前为了它进行的操作可以不算了。
  • 在每次窗口移动后,更新ans为当前anscnt_w的较小值,因为我们要找的是最少操作次数。

流程展示

代码

class Solution:
    def minimumRecolors(self, blocks: str, k: int) -> int:
        ans = cnt_w = blocks[:k].count('W')
        for in_, out in zip(blocks[k:], blocks):
            cnt_w += (in_ == 'W') - (out == 'W')
            ans = min(ans, cnt_w)
        return ans

复杂度分析

  • 时间复杂度:O(n),其中 n 为 blocks 的长度。
  • 空间复杂度:O(1),仅用到若干额外变量。
  • 19
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值