最小交换次数将二进制字符串变成交替字符串
题目描述
给定一个二进制字符串 s,要求将其转换为一个交替字符串。交替字符串定义为:相邻字符不相同的字符串。例如:
"010"和"1010"是交替字符串,"0100"不是交替字符串。
你可以任意交换字符串中两个字符的位置(不必是相邻的)。请计算将字符串转化为交替字符串所需的最小交换次数,如果无法完成转换,返回 -1。
题目分析
- 交替字符串的形式
对于长度为 n 的字符串,交替字符串只能有两种模式:
- 以 `0` 开头,依次是 `0, 1, 0, 1, ...`(记作模式 A)
- 以 `1` 开头,依次是 `1, 0, 1, 0, ...`(记作模式 B)
- 字符数量限制
由于字符必须交替出现,字符串中 0 和 1 的数量必须符合特定要求:
- 当 `n` 为偶数时,`0` 和 `1` 的数量必须相等,否则无法构成交替字符串。
- 当 `n` 为奇数时,`0` 和 `1` 的数量只能相差 1,且以哪个字符开头决定了哪个字符数量多 1。
- 能否转换
如果字符串中 0 和 1 的数量不满足上述条件,那么无论如何交换都无法形成交替字符串,应返回 -1。
- 计算最小交换次数
假设字符串可以转化为某种交替模式,我们需要最少的交换次数。交换时:
- 每次交换两个字符,能够同时解决两个不匹配的位置。
- 因此,最小交换次数 = 不匹配字符对的数量 / 2。
解题方法
- 计算字符串中
0和1的数量,记为count0和count1。 - 根据字符串长度
n,判断两种交替模式的字符数量需求:- 模式 A:偶数位置为
0,奇数位置为1 - 模式 B:偶数位置为
1,奇数位置为0
- 模式 A:偶数位置为
- 判断
count0和count1是否符合这两种模式的数量要求。 - 对符合条件的模式,计算字符串中与目标模式不匹配的字符数
diff。 - 最小交换次数为
diff // 2。 - 若两种模式均符合条件,则取最小交换次数;否则返回 -1。
代码实现(Python)
class Solution:
def minSwaps(self, s: str) -> int:
n = len(s)
count0 = s.count('0')
count1 = n - count0
def count_diff(target: str) -> int:
diff = 0
for i, ch in enumerate(s):
if ch != target[i]:
diff += 1
return diff // 2 # 每次交换修正两个错误
# 构造两种交替字符串
alt1 = ''.join('0' if i % 2 == 0 else '1' for i in range(n)) # 010101...
alt2 = ''.join('1' if i % 2 == 0 else '0' for i in range(n)) # 101010...
res = []
# 形态1需要的0和1数
need0_alt1 = (n + 1) // 2
need1_alt1 = n // 2
# 形态2需要的0和1数
need0_alt2 = n // 2
need1_alt2 = (n + 1) // 2
if count0 == need0_alt1 and count1 == need1_alt1:
res.append(count_diff(alt1))
if count0 == need0_alt2 and count1 == need1_alt2:
res.append(count_diff(alt2))
return min(res) if res else -1
代码说明
count0和count1用来判断字符串是否可能转换成交替字符串。alt1和alt2是两种交替模式的目标字符串。count_diff计算当前字符串和目标字符串的不同字符个数,返回差异一半作为交换次数。- 最后判断能否转换成模式 A 或模式 B,若都不符合返回 -1。
示例说明
| 输入 | 输出 | 说明 |
|---|---|---|
"111000" | 1 | 可交换一个位置使字符串变成 "101010"或 "010101"。 |
"010" | 0 | 已经是交替字符串,无需交换。 |
"111" | -1 | 只有1,没有0,无法构成交替字符串。 |
"1001" | 1 | 交换中间两个字符变成 "1010"。 |
方法分析和比较
| 方法 | 时间复杂度 | 空间复杂度 | 备注 |
|---|---|---|---|
| 枚举两种模式 | O(n) | O(n) | 构造目标字符串,计算差异 |
| 优化(位运算) | O(n) | O(1) | 可直接计算不匹配次数,无需存储目标字符串 |
本题由于字符串长度通常不是特别大,使用构造目标字符串的方法已经非常高效且易读。复杂度为 O(n),空间 O(n),性能优良。
总结
- 本题核心是判断是否有合适的
0和1数量分布,才能构成交替字符串。 - 利用两种可能的目标模式匹配原字符串,计算不匹配位置的数量。
- 最小交换次数等于不匹配位置数量的一半。
- 任意交换使问题简化,不需要考虑复杂的交换路径。
该思路简洁高效,易于理解和实现,适合类似的二进制字符串转换问题。
413

被折叠的 条评论
为什么被折叠?



