最少字符串操作次数题解 | 豆包MarsCode AI 刷题

54 阅读3分钟

问题的核心是,如何通过尽量少的操作将字符串中的所有字符变成唯一的字符。每次操作是删除两个相同的字符,并且在字符串的末尾添加一个新的字符。我们的目标是通过这些操作使得所有字符不重复。

解题思路

我们可以从字符频率入手,首先统计每个字符在字符串中出现的次数,然后根据字符的重复情况来决定需要多少次操作。

步骤解析

  1. 统计频率: 首先统计字符串中每个字符的出现次数。比如,字符串 "aabbcc" 中,a 出现2次,b 出现2次,c 出现2次。
  2. 操作条件: 每次操作可以删除两个相同的字符,因此如果某个字符出现了 n 次,那么我们可以通过 n // 2 次操作消除掉一部分重复字符。剩下的字符数量是 n % 2
  3. 目标: 最终我们希望每个字符的频率都为1。我们需要通过这些操作将字符频率从大于1的状态减少到1。操作过程中,删除两个相同字符后添加一个新字符,实际上是“消耗”掉一对重复字符,并替换为一个新的字符。这个新的字符可能会与其他字符重复,因此我们需要保持对新字符的频率管理。
  4. 最终判断: 计算最终需要的操作次数,确保所有字符的频率都为1。

具体算法

  1. 频率统计:首先统计每个字符的频率。
  2. 计算需要的操作次数:对于每个字符,如果它的频率大于1,则需要进行删除操作。每次删除两相同字符并替换为一个新的字符,操作次数即为字符频率的半数。
  3. 维护一个新字符池:在每次删除后,将新字符加入到待处理池中,直到所有字符都变为唯一字符。

代码实现

pythonCopy Code
from collections import Counter

def min_operations(S):
    # 统计字符串中每个字符的频率
    freq = Counter(S)
    
    # 记录操作次数
    operations = 0
    
    # 需要处理的字符池,初始化为空
    new_char_pool = 0
    
    for count in freq.values():
        if count > 1:
            # 每对相同的字符,我们进行一次操作
            operations += count // 2
            # 剩余的字符数,如果为奇数,则可能还需要进一步操作
            new_char_pool += count % 2
    
    # 如果剩余的字符数是奇数的话,需要再进行一次操作
    if new_char_pool > 0:
        operations += 1
    
    return operations

# 示例
S = "aabbcc"
print(min_operations(S))  # 输出: 3

代码解释

  1. Counter(S) :用来统计字符串 S 中每个字符出现的次数,返回一个字典类型,键是字符,值是该字符的频次。
  2. operations:记录总共进行的操作次数。
  3. new_char_pool:记录需要被替换的字符对数。例如,如果有3个字符相同,new_char_pool 会增加 1,因为剩下 1 个字符是无法再匹配对的,可能需要一个新的字符来替代。
  4. 最终根据 new_char_pool 是否存在奇数个剩余字符来判断是否需要额外的操作。

时间复杂度分析

  • 统计字符频率的时间复杂度是 O(n),其中 n 是字符串的长度。
  • 对于每个字符的频次,我们计算其需要的操作次数的复杂度是 O(1)。
  • 因此,整体时间复杂度是 O(n)。

结论

通过上述算法,我们能够高效地计算出将字符串中所有字符都变成唯一字符所需的最少操作次数。