1. 问题背景与理解
这道LeetCode 1888题看似简单,却暗藏玄机。我们需要通过最少的翻转操作(将'0'变为'1'或反之)使二进制字符串变成交替字符串。所谓交替字符串,就是相邻字符不同的字符串,比如"0101"或"1010"。
在实际工程中,类似的问题常出现在数据校验、信号处理等领域。比如在通信系统中,避免长串连续的0或1有助于时钟恢复;在存储系统中,交替模式可以减少电流尖峰。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路分析
2.1 暴力解法及其局限
最直观的方法是尝试所有可能的交替模式。对于长度为n的字符串,只有两种可能的交替模式:
- 以0开头的模式(0101...)
- 以1开头的模式(1010...)
对于每种模式,我们可以计算需要翻转的次数,然后取最小值。这种方法的时间复杂度是O(n),空间复杂度是O(1)。
但题目有个关键限制:可以删除任意字符(删除不算操作次数)。这使得问题复杂度骤增,因为删除不同位置的字符会影响最终的交替模式。
2.2 关键观察点
经过分析,我们发现几个重要性质:
- 删除字符相当于选择子序列
- 最终字符串的长度奇偶性会影响交替模式
- 最优解一定满足:删除后的字符串要么全是以0开头,要么全是以1开头的交替序列
3. 动态规划解法详解
3.1 状态定义
定义两个状态数组:
zero[i]:处理前i个字符,以0结尾的交替序列的最小翻转次数one[i]:处理前i个字符,以1结尾的交替序列的最小翻转次数
3.2 状态转移方程
对于第i个字符s[i]:
- 如果s[i] == '0':
zero[i] = one[i-1]one[i] = zero[i-1] + 1
- 如果s[i] == '1':
zero[i] = one[i-1] + 1one[i] = zero[i-1]
同时维护一个全局最小值min_operations,在每一步更新可能的最小值。
3.3 实现示例
python复制def minFlips(s: str) -> int:
n = len(s)
# 初始状态
zero, one = 0, 0
min_ops = f
