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

42 阅读4分钟

问题描述

小U得到一个只包含小写字母的字符串 S。她可以执行如下操作:每次选择字符串中两个相同的字符删除,然后在字符串末尾添加一个任意的小写字母。小U想知道,最少需要多少次操作才能使得字符串中的所有字母都不相同?

测试样例

样例1:

输入:S = "abab"
输出:2

样例2:

输入:S = "aaaa"
输出:2

样例3:

输入:S = "abcabc"
输出:3

解决思路

要解决这个问题,我们需要详细分析小U的操作过程,以及如何通过一系列步骤来最小化操作次数,使得字符串S中的所有字母都不相同。以下是详细的解题思路:

  1. 统计字符出现次数

    • 首先,我们需要统计字符串S中每个字符出现的次数。这可以通过使用一个数组或者HashMap来实现,其中键是字符,值是该字符出现的次数。由于字符串只包含小写字母,我们可以使用一个长度为26的数组来存储每个字母的出现次数,数组的索引对应字母表中的位置。
  2. 计算需要删除的字符对数

    • 接下来,我们需要计算需要删除的字符对数。遍历这个统计结果,对于每个出现次数大于1的字符,我们需要删除多余的字符对。例如,如果字符'a'出现了4次,我们需要删除2对'a'(即4个'a')。这样,我们就可以得到需要删除的字符对总数。
  3. 计算最少操作次数

    • 由于每次删除操作后,我们可以在末尾添加一个新的字符,所以对于每个需要删除的字符对,我们实际上只需要进行一次操作。因此,需要的操作次数就是需要删除的字符对总数。这一步是解题的关键,因为它直接关系到我们需要进行多少次操作。
  4. 处理剩余字符

    • 在删除了所有多余的字符对之后,字符串中可能还有一些字符出现次数为1,这些字符不需要进一步操作。但是,如果字符串长度大于26(即字母表的大小),我们还需要继续添加新的字符,直到所有字符都不相同。这意味着,如果字符串长度减去不同字符的数量大于26,我们还需要额外添加一些操作。
  5. 优化操作

    • 在实际操作中,我们可以通过一些优化来减少不必要的操作。例如,我们可以先删除出现次数最多的字符对,这样可以更快地减少字符串中字符的重复度。
  6. 特殊情况处理

    • 我们需要考虑一些特殊情况,比如字符串S中已经包含了所有26个字母,或者某个字符的出现次数远大于其他字符。这些情况可能需要我们采取不同的策略来最小化操作次数。
  7. 算法实现

    • 通过上述分析,我们可以编写一个算法来实现这个过程。算法的基本步骤包括:统计字符出现次数、计算需要删除的字符对数、计算最少操作次数、处理剩余字符,以及特殊情况处理。
  8. 总结

    • 这个问题的解决关键在于理解如何通过一系列操作来最小化操作次数,使得字符串中的所有字母都不相同。通过统计字符出现次数、计算需要删除的字符对数、以及处理剩余字符,我们可以找到最少需要的操作次数。这种方法不仅适用于小字符串,也适用于大字符串,因为它不依赖于字符串的大小,而是依赖于字符的分布。

代码解析

public class Main {
    public static int solution(String S) {
        // write code here
        // 1. 统计不同字符的相同的数量,放到一个数组中(数频)
        // 2. 判断奇数或者偶数 以及2的倍数
        int []count=new int[26];
        for(char c:S.toCharArray())
        {
            count[c-'a']++;
        }

        int operations=0;
        for(int freq:count)
        {
            if(freq>1)
            {
                operations+=freq/2;
            }
        }

        return operations;
    }

    public static void main(String[] args) {
        System.out.println(solution("abab") == 2);
        System.out.println(solution("aaaa") == 2);
        System.out.println(solution("abcabc") == 3);
    }
}