青训营X豆包MarsCode 技术训练营第二课 | 豆包MarsCode AI 刷题

2 阅读3分钟

问题描述

给定一个字符串 ss,你需要通过删除一些字符,使得每个字符在字符串中出现的次数均不相同。你需要找出最少需要删除的字符数量以达到这个目标。

例如,对于字符串 "aab",字符 "a" 出现2次,字符 "b" 出现1次,这些出现次数已经不同,因此不需要删除任何字符,输出为0。


测试样例

样例1:

输入:s = "aab"
输出:0

样例2:

输入:s = "aaabbbcc"
输出:2

样例3:

输入:s = "abcdef"
输出:5 要解决这个问题,我们需要找到最少需要删除的字符数量,使得每个字符在字符串中出现的次数均不相同。具体步骤如下:

  1. 统计字符出现次数:首先统计字符串中每个字符的出现次数。

  2. 排序出现次数:将出现次数按从大到小排序。

  3. 调整出现次数:从最大的出现次数开始,逐个调整出现次数,使得每个出现次数均不相同。

  4. 计算删除的字符数量:记录调整过程中删除的字符数量。

  5. 统计字符出现次数:使用 Counter 统计字符串中每个字符的出现次数。

  6. 排序出现次数:将出现次数按从大到小排序。

  7. 调整出现次数:从最大的出现次数开始,逐个调整出现次数,使得每个出现次数均不相同。

    • 如果当前出现次数大于等于前一个出现次数,则将其减1,并记录删除的字符数量。
  8. 计算删除的字符数量:记录调整过程中删除的字符数量。

复杂度分析:

  • 时间复杂度O(n log n),其中 n 是字符串的长度。统计字符出现次数的时间复杂度为 O(n),排序的时间复杂度为 O(n log n),调整出现次数的时间复杂度为 O(n)
  • 空间复杂度O(n),用于存储字符出现次数的计数器。

这个实现能够正确找到最少需要删除的字符数量,使得每个字符在字符串中出现的次数均不相同,并且在合理的时间内处理较小的输入。对于较大的输入,可能需要进一步优化。

def solution(s: str) -> int:
    from collections import Counter

    # 统计每个字符的出现频率
    frequency = Counter(s)
    
    # 用于记录已经使用过的频率
    used_frequencies = set()
    deletions = 0  # 记录需要删除的字符数量

    # 对频率进行排序,从高到低处理
    for count in sorted(frequency.values(), reverse=True):
        # 如果这个频率已经被使用过
        while count > 0 and count in used_frequencies:
            count -= 1  # 将频率减1
            deletions += 1  # 记录删除的字符数量
        used_frequencies.add(count)  # 将这个频率标记为已使用

    return deletions

# 测试代码
if __name__ == '__main__':
    print(solution(s="aab") == 0)
    print(solution(s="aaabbbcc") == 2)
    print(solution(s="abcdef") == 5)