青训营X豆包MarsCode 技术训练营 AI刷题31. 不同整数的计数问题 | 豆包MarsCode AI 刷题

62 阅读4分钟

问题描述

小R有一个字符串 word,该字符串由数字和小写英文字母组成。小R想用空格替换每一个不是数字的字符。然后,他希望统计在替换后剩下的整数中,不同整数的数目。

例如,给定字符串 "a123bc34d8ef34",替换后形成的字符串是 " 123 34 8 34",剩下的整数是 "123""34""8" 和 "34"。不同的整数有三个,即 "123""34" 和 "8"

注意,只有当两个整数的不含前导零的十进制表示不同,才认为它们是不同的整数。


测试样例

样例1:

输入:word = "a123bc34d8ef34"
输出:3

样例2:

输入:word = "t1234c23456"
输出:2

样例3:

输入:word = "a1b01c001d4"
输出:2

问题分析

题目要求:给定一个字符串 word,其中包含数字和小写英文字母。你需要做以下两件事情:

  1. 用空格替换每个不是数字的字符(即字母)。
  2. 统计在替换后的字符串中,出现的不同整数的数量。需要注意,整数不能有前导零,且相同数值的整数应该只计数一次。

解题思路

  1. 提取数字子串:

    • 我们首先需要遍历整个字符串,将其中的数字部分提取出来,跳过非数字字符。这里可以利用字符串的遍历和条件判断来提取连续的数字。
  2. 处理前导零:

    • 在提取数字时,我们要注意去掉前导零。比如,0012 和 12 代表同一个数字。可以利用 stoi(字符串转整数)来自动去除前导零。
  3. 统计不同的整数:

    • 将提取出的整数存储到一个集合(unordered_set)中,这样集合会自动处理重复的数字。最终集合的大小就是不同整数的个数。

1. 辅助函数:

bool is_num(char c){
    return c >= '0' && c <= '9';  // 判断字符是否是数字
}

bool is_word(char c){
    return c >= 'a' && c <= 'z';  // 判断字符是否是字母
}
  • is_num 判断一个字符是否为数字。
  • is_word 判断一个字符是否为字母。这两个函数基本上是为了让代码更简洁和可读。

2. 核心解题逻辑:

int solution(string word) {
    unordered_set<int> hash_num;  // 用于记录该数值是否已经出现
    int num_count = 0;  // 不同整数的个数
    int left = 0, right = 0;  // 左右指针

    while (right < word.size()) {
        if (is_num(word[right])) {  // 如果字符是数字
            if (right + 1 == word.size() || is_word(word[right + 1])) {  // 判断当前数字是否是一个完整的数字
                int num = stoi(word.substr(left, right - left + 1));  // 提取数字并转化为整数
                if (hash_num.find(num) == hash_num.end()) {  // 如果数字不在集合中
                    num_count++;  // 计数增加
                    hash_num.insert(num);  // 插入集合
                }
                left = right + 1;  // 更新左指针,指向下一个字符
            }
        } else {  // 如果字符是字母
            left++;  // 跳过字母
        }
        right++;  // 移动右指针
    }
    return num_count;  // 返回不同整数的个数
}

3. 解释代码逻辑:

  • unordered_set<int> hash_num 用于存储已经处理过的整数。集合保证了整数的唯一性,因此我们只会统计不同的整数。
  • num_count 用于记录不同整数的个数。
  • left 和 right 是两个指针,left 用来标记数字的起始位置,right 用来遍历字符串。每次当遇到一个数字并且到达一个完整数字的结尾时,我们提取这个数字并转换为整数(去掉前导零)。然后,我们检查这个整数是否已经出现过,如果没有,则增加 num_count,并将该整数插入 unordered_set 中。

4. 细节处理:

  • 数字的提取:  通过 stoi 函数,将字符串中的数字转换为整数时,自动去除前导零。这样,0012 和 12 会被处理为相同的数字。
  • left 和 right 的更新:  当我们找到一个完整的数字时,left 更新为 right + 1,准备处理下一个可能的数字。如果 right 遇到字母,left 向后移动一位,跳过当前字母。

image.png