LeetCode2864.使二进制字符串交替的最小翻转次数【中等】
LeetCode 2864. 使二进制字符串交替的最小翻转次数
题目链接: https://leetcode.cn/problems/minimum-number-of-flips-to-make-the-binary-string-alternating/
日期: 2026-03-07
难度: Medium
标签: 滑动窗口、字符串、贪心
题目描述
给定一个二进制字符串 s,你可以执行两种操作:
- 将首元素移到末尾(循环移位)
- 任选一个元素反转(0→1 或 1→0)
求将 s 转换成交替字符串(如 “010101…” 或 “101010…”)所需的最少操作 2 的次数。
解题思路
关键洞察
操作 1 的本质:不需要真正去截取首元素放到末尾,而是通过 拼接
s + s来模拟循环移位。这样问题转化为:在长度为2n的字符串中,找一个长度为n的窗口,使其最接近目标交替串。滑动窗口优化:如果暴力遍历每个窗口的所有元素,时间复杂度为 O(n²),不可接受。关键观察是:窗口每次只滑动一格,只有左右边界元素发生变化,中间元素不变。因此可以用一个全局变量
diff维护当前窗口的总差异数。窗口滑动规则:
- 离开的旧字符:如果原本与目标不同,差异数
-1 - 进入的新字符:如果与目标不同,差异数
+1
- 离开的旧字符:如果原本与目标不同,差异数
两种目标模式:交替串有两种可能:
- 以
0开头:010101... - 以
1开头:101010...
需要分别计算两种情况,取最小值。
- 以
代码实现
class Solution { |
复杂度分析
| 复杂度 | 分析 |
|---|---|
| 时间复杂度 | O(n) - 构建目标串 O(n),初始化窗口 O(n),滑动窗口 O(n) |
| 空间复杂度 | O(n) - doubleS 和两个目标串各占 O(n) |
心得总结
思维转折点
一开始的思路停留在模拟字符串操作:每次拼接后遍历整个字符串与目标串比较。这个思路虽然直观,但时间复杂度 O(n²) 会超时。
真正的突破来自两点:
s + s的巧妙转换:将循环移位问题转化为滑动窗口问题,这是本题的第一层关键。- 滑动窗口的增量更新:意识到窗口滑动时只需处理边界元素,这是第二层关键,也是滑动窗口思想的精髓。
滑动窗口的核心思想
提到滑动窗口,就要想到避免重复遍历窗口内所有元素。不同题目有不同的维护方式:
| 题目类型 | 维护方式 |
|---|---|
| 最长连续子数组 | 按条件收缩左边界 |
| 滑动窗口最大值 | 单调队列 (deque) |
| 本题 | 增量更新差异计数 |
经验教训
- 看到循环/旋转问题,优先考虑
s + s拼接技巧 - 滑动窗口的核心是利用相邻窗口的重叠部分,只做增量计算
- 交替串问题通常有两种模式,都要考虑
相关题目
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Chippandaの技术小站!
