【030】计算"组成字符串ku的最大次数" | 豆包MarsCode AI 刷题

53 阅读5分钟

前言

在字符串处理中,经常会遇到要求从给定的字符串中组成特定子字符串的问题。这个问题的重点在于:从一个由任意大小写字母组成的字符串中,计算出能够最多组成多少个"ku"的子字符串。在该题中,我们不仅要注意字符的大小写问题(忽略大小写),还要考虑字符的使用次数限制。

题目

image.png

问题分析

该问题的核心目标是从给定的字符串中计算出最多能组成多少个 "ku" 字符串。我们可以从以下几个方面进行详细分析:

字符的计数关系

要组成一个 "ku" 字符串,我们需要有至少一个 'k' 和一个 'u'。因此,从一个字符串中组成 "ku" 的数量,取决于 'k' 和 'u' 字符的出现次数。具体而言,假设在字符串中出现了 countK 个 'k' 字符,countU 个 'u' 字符,那么最多能够组成 min(countK, countU) 个 "ku"。

  • 如果 'k' 比 'u' 更多,最多能组成的 "ku" 数量就受限于 'u' 的数量,因为每个 "ku" 都需要一个 'u'。
  • 反之,如果 'u' 比 'k' 更多,最多能组成的 "ku" 数量就受限于 'k' 的数量。
  • 如果两者数量相同,那么最多能组成的 "ku" 数量即为两者的数量。
忽略字符的大小写

题目明确指出,字符的大小写是不敏感的,这意味着我们可以忽略大小写的区别进行处理。

字符串长度和字符遍历

字符串的遍历是解决该问题的关键。我们需要遍历整个字符串,统计其中 'k' 和 'u' 字符的出现次数。为了确保遍历过程高效,我们只需要遍历一次字符串,每次遇到 'k' 或 'u' 就增加对应的计数器。这种方法的时间复杂度是 O(n),其中 n 是字符串的长度。

如何确定最多能组成多少个 "ku"

每次组成一个 "ku" 都需要消耗一个 'k' 和一个 'u'。因此,能够组成的最大数量完全由 'k' 和 'u' 的数量决定。可以通过以下两种直观的方式来理解:

  • 假设字符串中有 countK 个 'k' 和 countU 个 'u'。那么,最多能够组成的 "ku" 数量就是 Math.min(countK, countU)
  • 例如,如果有 5 个 'k' 和 3 个 'u',那么最多能组成 3 个 "ku",因为每个 "ku" 都需要一个 'k' 和一个 'u'。

通过上述分析,我们可以得出结论:解决该问题的核心是统计字符串中 'k' 和 'u' 的数量,忽略其他字符和大小写差异。由于每个 "ku" 都需要一个 'k' 和一个 'u',最终能够组成的 "ku" 数量是 'k' 和 'u' 数量中的较小值。这种方法非常高效,能够在 O(n) 的时间复杂度内解决问题,适用于大规模的输入。

思路

1. 统一字符大小写

题目中提到,字符大小写不敏感,即大写字母和小写字母视为相同。因此,我们首先需要将字符串中的所有字符转换为小写。这样可以避免在后续统计时,区分大小写的复杂性,简化问题。

2. 统计字符的出现次数

在转换为小写后,我们的任务是统计字符串中 'k' 和 'u' 字符的出现次数。这是因为每次组成一个 "ku" 字符串,都需要一个 'k' 和一个 'u'。因此,问题的关键就是计算这两个字符的数量。

3. 计算能够组成的最大 "ku" 数量

要组成一个 "ku" 字符串,我们需要一个 'k' 和一个 'u'。因此,能够组成的最大数量是 'k' 和 'u' 出现次数的较小值。即,能够组成的 "ku" 数量 = min(统计到的 'k' 数量, 统计到的 'u' 数量)

4. 返回结果

最后,我们返回 min(countK, countU) 的值,即从字符串中最多能够组成的 "ku" 数量。

具体的步骤流程如下:

  1. 将输入字符串转换为小写。
  2. 遍历字符串,统计其中 'k' 和 'u' 的出现次数。
  3. 计算并返回两者的较小值,即能够组成的最大 "ku" 数量。

代码

以下具体实现的代码(基于Java)

public class Main {
    public static int solution(String s) {
        // 将字符串转换为小写方便统计
        s = s.toLowerCase();

        // 统计 'k' 和 'u' 的出现次数
        int countK = 0;
        int countU = 0;

        for (char c : s.toCharArray()) {
            if (c == 'k') {
                countK++;
            } else if (c == 'u') {
                countU++;
            }
        }

        // 能组成的 "ku" 的数量是两者的较小值
        return Math.min(countK, countU);
    }

    public static void main(String[] args) {
        System.out.println(solution("AUBTMKAxfuu") == 1); // true
        System.out.println(solution("KKuuUuUuKKKKkkkkKK") == 6); // true
        System.out.println(solution("abcdefgh") == 0); // true
    }
}

分析一下上述代码

  • 字符串转换为小写

    • 通过调用 s.toLowerCase(),我们将整个字符串统一转化为小写,确保字符的大小写不影响统计结果。
  • 字符计数

    • 我们使用两个计数器 countKcountU 分别统计 'k' 和 'u' 的出现次数。
    • 遍历字符串中的每个字符,若是 'k',则 countK 加 1,若是 'u',则 countU 加 1。
  • 计算结果

    • 组成 "ku" 的最大次数是 'k' 和 'u' 的数量中较小的那个,使用 Math.min(countK, countU) 来得到最终结果。

复杂度分析

  • 时间复杂度:遍历一次字符串,统计 'k' 和 'u' 的次数,时间复杂度为 O(n),其中 n 是字符串的长度。
  • 空间复杂度:我们只使用了常数级别的额外空间来存储计数器,因此空间复杂度为 O(1)。

最后

通过本题的分析和代码实现,我们可以轻松地解决从字符串中组成最多 "ku" 的问题。这个问题主要考察了字符串的遍历、字符统计和大小写处理。该算法的时间复杂度为 O(n),适用于较大规模的输入,并且由于仅需要常数空间,因此具有较高的空间效率。