1. 问题背景与理解
这道题目来自LeetCode第170场双周赛的第一题,编号3750。题目要求我们计算将一个二进制字符串通过最少次数的反转操作变成全"0"或全"1"字符串所需的最小操作次数。这类字符串操作问题在实际编程面试和算法竞赛中非常常见,特别是在处理二进制数据、状态转换等场景时。
二进制字符串的反转操作通常指的是将字符串中的某个子串进行"翻转"——即把其中的'0'变成'1','1'变成'0'。例如,对于字符串"0101",反转子串[1,3](从第2个字符到第4个字符,假设索引从0开始)会得到"0010"。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题分析与解法思路
2.1 问题重述
给定一个二进制字符串s,我们可以执行以下操作任意次数:
- 选择s的一个子串,并将该子串中的每个字符反转('0'变'1','1'变'0')
我们需要计算将s变成全"0"或全"1"所需的最少操作次数。
2.2 关键观察
解决这个问题的关键在于观察字符串中连续相同字符的块(block)。例如,字符串"00110011"可以看作是由4个块组成的:两个'0',接着两个'1',然后两个'0',最后两个'1'。
一个重要观察是:每次反转操作最多可以减少两个块。具体来说:
- 如果我们反转一个位于字符串中间的块(既不是第一个也不是最后一个块),那么可以减少两个块
- 如果我们反转第一个或最后一个块,则只能减少一个块
2.3 贪心算法思路
基于上述观察,我们可以采用贪心算法来解决这个问题:
- 统计字符串中从'0'开始的块的数量(cnt0)和从'1'开始的块的数量(cnt1)
- 将字符串变为全'0'所需的最少操作次数为⌈cnt0/2⌉
- 将字符串变为全'1'所需的最少操作次数为⌈cnt1/2⌉
- 取两者中的较小值作为答案
2.4 数学证明
为什么这个贪心策略是正确的?让我们从数学角度来理解:
- 每次操作最多可以减少两个块(当反转中间块时)
- 最少可以减少一个块(当反转第一个或最后一个块时)
- 因此,最少需要的操作次数就是块数除以2并向上取整
3. 具体实现与代码
3.1 Python实现
python复制def minFlips(s: str) -> int:
# 统计以'0'开头的块数和以'1'开
