leetcode 2026-03-05 每日一练 - 生成交替二进制字符串的最少操作数

leetcode 2026-03-05 每日一练 - 生成交替二进制字符串的最少操作数
Austoin题目描述
LeetCode 1758. 生成交替二进制字符串的最少操作数
给你一个仅由字符 '0' 和 '1' 组成的字符串 s。一步操作中,你可以将任一 '0' 变成 '1',或者将 '1' 变成 '0'。
交替字符串定义为:如果字符串中不存在相邻两个字符相等的情况,那么该字符串就是交替字符串。例如,字符串 "010" 是交替字符串,而字符串 "0100" 不是。
返回使 s 变成交替字符串所需的最少操作数。
示例 1:
- 输入:
s = "0100" - 输出:
1 - 解释:如果将最后一个字符变为
'1',s就变成"0101",即符合交替字符串定义
示例 2:
- 输入:
s = "10" - 输出:
0 - 解释:
s已经是交替字符串
示例 3:
- 输入:
s = "1111" - 输出:
2 - 解释:需要 2 步操作得到
"0101"或"1010"
解题思路
核心观察
交替二进制字符串只有两种可能的模式:
- 模式 A:以
0开头,即"010101..."(偶数位置为0,奇数位置为1) - 模式 B:以
1开头,即"101010..."(偶数位置为1,奇数位置为0)
贪心策略
由于只有两种目标模式,我们可以:
- 计算将字符串转换为模式 A 需要的操作数
- 计算将字符串转换为模式 B 需要的操作数
- 取两者的最小值
关键发现:如果转换为模式 A 需要 x 次操作,那么转换为模式 B 需要 len(s) - x 次操作。
原因:每个位置要么符合模式 A,要么符合模式 B,两者互补。
算法步骤
- 遍历字符串,统计不符合模式 A(以
0开头)的位置数量,记为ans - 模式 A 的期望:偶数位置为
0,奇数位置为1 - 如果
s[i]不等于i % 2,说明该位置需要修改 - 返回
min(ans, len(s) - ans),即两种模式中操作数较少的那个
代码实现
方法一:贪心算法(推荐)
1 | func minOperations(s string) int { |
方法二:显式计算两种模式(备选)
1 | func minOperations(s string) int { |
核心细节
- 模式互补性:两种模式的操作数之和等于字符串长度,因此只需计算一种模式
- 位置判断:使用
i % 2判断当前位置应该是0还是1 - 字符转换:
v - '0'将字符'0'或'1'转换为整数0或1 - 贪心正确性:由于每个位置独立,局部最优即全局最优
复杂度分析
方法一
- 时间复杂度:
O(n),只需遍历字符串一次 - 空间复杂度:
O(1),只使用常量额外空间
方法二
- 时间复杂度:
O(n),遍历字符串一次 - 空间复杂度:
O(1),只使用常量额外空间
方法对比
| 方法 | 优点 | 缺点 |
|---|---|---|
| 方法一 | 代码简洁,利用互补性 | 需要理解互补关系 |
| 方法二 | 逻辑直观,易于理解 | 代码较长,重复判断 |
推荐使用方法一,代码更简洁高效。
示例分析
示例 1:s = "0100"
模式 A(”0101”):
- 位置 0:
'0'期望'0'✓ - 位置 1:
'1'期望'1'✓ - 位置 2:
'0'期望'0'✓ - 位置 3:
'0'期望'1'✗(需要修改) - 操作数:1
模式 B(”1010”):
- 需要修改位置 0、1、2,共 3 次操作
结果:min(1, 3) = 1
示例 3:s = "1111"
模式 A(”0101”):
- 位置 0、2 需要修改,共 2 次操作
模式 B(”1010”):
- 位置 1、3 需要修改,共 2 次操作
结果:min(2, 2) = 2
总结
这道题的关键点:
- 理解交替字符串只有两种模式:
"010101..."和"101010..." - 利用模式互补性:两种模式的操作数之和等于字符串长度
- 贪心策略:只需计算一种模式的操作数,另一种自动得出
- 一次遍历:通过
i % 2判断期望值,统计不匹配的位置数













