小G的平衡串转换 | 豆包MarsCode AI刷题

69 阅读2分钟

一、问题描述

“平衡串”仅由字符 abc 组成,并且满足条件:字符 a 的数量等于字符 bc 的数量之和。给定一个由字符 abc 组成的字符串 s,我们可以通过每次操作将任意一个字符修改为其他任意字符。目标是计算出将字符串 s 转变为“平衡串”所需的最少操作次数。

例如:

  • 输入字符串 s = "abca",已经是平衡串,无需操作。
  • 输入字符串 s = "abbc",需要一次操作将一个 bc 转为 a,才能使其变为平衡串。
  • 保证字符串 s 的长度为偶数。

二、问题分析

  1. 平衡条件

    • 字符串要满足“平衡串”条件,即 a 的数量等于 bc 的数量之和。我们可以表示为:count(a) == count(b) + count(c)
  2. 操作的必要性

    • 对于任意字符串 s,每次改变目标是让 count(a)count(b) + count(c) 尽可能接近,bc字符在本质上没有差别,即改变bc没有意义,故只考虑两种操作:
    • count(a) 多于 count(b) + count(c),则需要将部分 a 转变为 bc
    • count(a) 少于 count(b) + count(c),则需要将部分 bc 转变为 a
  3. 最小操作次数

    • 对于平衡条件,我们可以得到一个最小操作次数是调整这两者差值的一半,即 abs(count(a) - (count(b) + count(c))) / 2

三、解题思路

  1. 统计字符数量

    • 遍历字符串,统计字符 a 的数量 num_a
    • 用字符串长度减去 num_a,得到字符 bc 的数量之和 num_bc
  2. 计算操作次数

    • 如果 num_anum_bc 不相等,计算二者差值的一半即可得到需要的最少操作次数,因为一次操作可以让差值减少 2。由于字符串长度保证为偶数,所以差值也一定是偶数,得到结果不用做取整处理。

四、代码实现

def solution(s: str) -> int:
    # 统计字符 'a' 的数量
    num_a = 0
    for c in s:
        if c == 'a':
            num_a += 1
    # 计算字符 'b' 和 'c' 的总数量
    num_bc = len(s) - num_a
    # 计算需要的最少操作次数,使 num_a 等于 num_bc
    return abs(num_a - num_bc) // 2

# 测试用例
if __name__ == '__main__':
    print(solution("abca") == 0)  # 输出 0,因为已经是平衡串
    print(solution("abbc") == 1)  # 输出 1
    print(solution("ccbcca") == 2)  # 输出 2

五、复杂度分析

  1. 时间复杂度

    • O(n),其中 n 是字符串的长度。代码通过一次遍历统计字符数量,复杂度为线性。
  2. 空间复杂度

    • O(1),只使用了常数级别的额外空间来存储计数结果和最终答案。

七、可优化方向

简化字符统计

  • 如果在大型数据或多种字符统计场景下,可以考虑使用 collections.Counter 统计字符频率。