不同整数的计数问题 | 豆包MarsCode AI刷题

31 阅读5分钟

问题描述

小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

算法设计

1、输入检查:

检查输入字符串是否为空,如果为空直接返回 0。

2、字符处理:

将输入字符串中的非数字字符替换为下划线 _,形成一个新的字符串。

3、字符串分割:

按下划线 _ 分割新字符串,得到一个包含数字字符串的数组。

4、集合存储:

将每个非空的数字字符串转换为整数,并存储到集合中,确保每个数字只出现一次。

5、结果返回:

返回集合的大小,即不同数字的数量。

复杂度分析

时间复杂度分析

  1. 字符处理
    • 遍历输入字符串的每个字符,时间复杂度为 O(n),其中 n** 是输入字符串的长度。
    • 对于每个字符,判断其是否为数字并进行相应的操作(追加到列表或追加下划线),这些操作都是常数时间复杂度 O(1)。
  1. 字符串分割
    • 将列表转换为字符串的操作是 O(n)。
    • 使用下划线分割字符串的操作也是 O(n),因为分割操作需要遍历整个字符串。
  1. 集合存储
    • 遍历分割后的字符串数组,时间复杂度为 O(m),其中 m** 是分割后的数组长度。
    • 对于每个非空的数字字符串,将其转换为整数并添加到集合中。集合的插入操作平均时间复杂度为 O(1)。
    • 因此,这一部分的时间复杂度为 O(m)。

综合以上步骤,总的时间复杂度为: O(n)+O(n)+O(m)=O(n+m)、

由于 m 是分割后的数组长度,最坏情况下 m 也是 O(n),因此总的时间复杂度为 O(n)。

空间复杂度分析

  1. 字符处理
    • 创建一个新的列表 sb 来存储处理后的字符,空间复杂度为 O(n)。
  1. 字符串分割
    • 将列表转换为字符串,空间复杂度为 O(n)。
    • 分割后的数组 split 的空间复杂度为 O(n),因为最坏情况下每个字符都是一个单独的子字符串。
  1. 集合存储
    • 创建一个集合 number_set 来存储不同的整数,空间复杂度为 O(k),其中 k 是不同整数的数量。最坏情况下,所有子字符串都是不同的整数,因此 kk 也是 O(n)。

综合以上步骤,总的空间复杂度为: O(n)+O(n)+O(n)+O(n)=O(n)

代码实现

Java 代码实现

import java.util.HashSet;
import java.util.Set;

class Main {
    public static int solution(String word) {
        // 检查输入字符串是否为空,如果为空则返回0
        if (word.isEmpty()) {
            return 0;
        }

        // 创建一个HashSet来存储不同的整数
        Set<Integer> set = new HashSet<>();

        // 将输入字符串转换为字符数组
        char[] charArray = word.toCharArray();

        // 创建一个StringBuilder来构建新的字符串
        StringBuilder sb = new StringBuilder();

        // 遍历字符数组
        for (char c : charArray) {
            // 如果字符是数字,将其追加到StringBuilder中
            if (c >= '0' && c <= '9') {
                sb.append(c);
            } else {
                // 如果字符不是数字,追加一个下划线
                sb.append('_');
            }
        }

        // 将StringBuilder转换为字符串
        String s = sb.toString();

        // 使用下划线分割字符串
        String[] split = s.split("_");

        // 遍历分割后的字符串数组
        for (String t : split) {
            // 如果子字符串不为空,将其转换为整数并添加到集合中
            if (!t.isEmpty()) {
                set.add(Integer.parseInt(t));
            }
        }

        // 返回集合中不同整数的数量
        return set.size();
    }

    public static void main(String[] args) {
        System.out.println(solution("a123bc34d8ef34") == 3);
        System.out.println(solution("t1234c23456") == 2);
        System.out.println(solution("a1b01c001d4") == 2);
    }
}

Python 代码实现

def solution(word: str) -> int:
    # 检查输入字符串是否为空,如果为空则返回0
    if not word:
        return 0

    # 创建一个集合来存储不同的整数
    number_set = set()

    # 创建一个空字符串来构建新的字符串
    sb = []

    # 遍历输入字符串的每个字符
    for c in word:
        # 如果字符是数字,将其追加到sb中
        if c.isdigit():
            sb.append(c)
        else:
            # 如果字符不是数字,追加一个下划线
            sb.append('_')

    # 将列表转换为字符串
    s = ''.join(sb)

    # 使用下划线分割字符串
    split = s.split('_')

    # 遍历分割后的字符串数组
    for t in split:
        # 如果子字符串不为空,将其转换为整数并添加到集合中
        if t:
            number_set.add(int(t))

    # 返回集合中不同整数的数量
    return len(number_set)

if __name__ == '__main__':
    print(solution("a123bc34d8ef34") == 3)
    print(solution("t1234c23456") == 2)
    print(solution("a1b01c001d4") == 2)