首先题目给出一个下标从 0 开始长度为 n 的字符串 blocks,其中 blocks}[i] 是 ‘W’ 或 ‘B’,分别表示白色块要么是黑色块。现在我们可以执行任意次将一个白色块转变为黑色块的操作,并给出一个整数 k,我们需要返回至少出现一次连续 k 个黑色块的最少操作次数。
我们可以用「滑动窗口」来解决该问题。我们用一个固定大小为 k 的「滑动窗口」表示出现连续 k 个黑色块的区间,我们需要将该区间全部变为黑色块,此时我们需要的操作次数为该区间中白色块的数目,那么我们只需要在「滑动窗口」从左向右移动的过程中维护窗口中白色块的数目,最后返回移动过程中白色块数目的最小值即为我们需要至少出现一次连续 k 个黑色块的最少操作次数。
代码
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defminimumRecolors(self, blocks: str, k: int) -> int: ans = inf cnt = 0 for i, ch inenumerate(blocks): if ch == 'W': cnt += 1 if i >= k and blocks[i-k] == 'W': cnt -= 1 if i >= k - 1: ans = min(ans, cnt) return ans
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { public: intminimumRecolors(string blocks, int k){ int l = 0, r = 0, cnt = 0; while (r < k) { cnt += blocks[r] == 'W' ? 1 : 0; r++; } int res = cnt; while (r < blocks.size()) { cnt += blocks[r] == 'W' ? 1 : 0; cnt -= blocks[l] == 'W' ? 1 : 0; res = min(res, cnt); l++; r++; } return res; } };
funcminimumRecolors(blocks string, k int)int { res := k left, whites := 0, 0 for right := 0; right < len(blocks); right++ { if blocks[right] == 'W' { whites++ } if right < k-1 { continue } res = min(res, whites) if blocks[left] == 'W' { whites-- } left++ } return res }
funcmin(a, b int)int { if a < b { return a } return b }