1864. 构成交替字符串需要的最小交换次数

最小交换次数将二进制字符串变成交替字符串

题目描述

给定一个二进制字符串 s,要求将其转换为一个交替字符串。交替字符串定义为:相邻字符不相同的字符串。例如:

  • "010""1010" 是交替字符串,
  • "0100" 不是交替字符串。

你可以任意交换字符串中两个字符的位置(不必是相邻的)。请计算将字符串转化为交替字符串所需的最小交换次数,如果无法完成转换,返回 -1。


题目分析

  1. 交替字符串的形式

对于长度为 n 的字符串,交替字符串只能有两种模式:

- 以 `0` 开头,依次是 `0, 1, 0, 1, ...`(记作模式 A)
- 以 `1` 开头,依次是 `1, 0, 1, 0, ...`(记作模式 B)
  1. 字符数量限制

由于字符必须交替出现,字符串中 01 的数量必须符合特定要求:

- 当 `n` 为偶数时,`0` 和 `1` 的数量必须相等,否则无法构成交替字符串。
- 当 `n` 为奇数时,`0` 和 `1` 的数量只能相差 1,且以哪个字符开头决定了哪个字符数量多 1。
  1. 能否转换

如果字符串中 01 的数量不满足上述条件,那么无论如何交换都无法形成交替字符串,应返回 -1。

  1. 计算最小交换次数

假设字符串可以转化为某种交替模式,我们需要最少的交换次数。交换时:

- 每次交换两个字符,能够同时解决两个不匹配的位置。
- 因此,最小交换次数 = 不匹配字符对的数量 / 2。

解题方法

  1. 计算字符串中 01 的数量,记为 count0count1
  2. 根据字符串长度 n,判断两种交替模式的字符数量需求:
    • 模式 A:偶数位置为 0,奇数位置为 1
    • 模式 B:偶数位置为 1,奇数位置为 0
  3. 判断 count0count1 是否符合这两种模式的数量要求。
  4. 对符合条件的模式,计算字符串中与目标模式不匹配的字符数 diff
  5. 最小交换次数为 diff // 2
  6. 若两种模式均符合条件,则取最小交换次数;否则返回 -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

代码说明

  • count0count1 用来判断字符串是否可能转换成交替字符串。
  • alt1alt2 是两种交替模式的目标字符串。
  • 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),性能优良。


总结

  • 本题核心是判断是否有合适的 01 数量分布,才能构成交替字符串。
  • 利用两种可能的目标模式匹配原字符串,计算不匹配位置的数量。
  • 最小交换次数等于不匹配位置数量的一半。
  • 任意交换使问题简化,不需要考虑复杂的交换路径。

该思路简洁高效,易于理解和实现,适合类似的二进制字符串转换问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值