青训营X豆包MarsCode 技术训练营第五课 |AI 刷题 不同整数的计数问题 题解 | 豆包MarsCode AI刷题

42 阅读3分钟

一.问题描述

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

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

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

二.思路分析

这个问题其实就是将字母之间的数字看成不同的整体,然后在去除每个数字前的前导零,最后将所有数字进行比较,算不重复的数字有多少。对此我们可以按照以下步骤进行:  

1..数据结构的选择

StringBuilder:用于构建替换后的字符串

Set:用于存储不同的整数,自动去重。

2.替换非数字字符:

遍历字符串 word 中的每个字符。

如果字符是数字(即在 '0' 到 '9' 之间),则保留;如果字符不是数字,则替换为空格。

3. 分割字符串

将替换后的字符串按照空格分割,得到一个字符串数组,每个元素都是一个可能的整数。

4.去除前导零

对于每一个候选整数,去除其前导零。例如,"00123" 变为 "123","08" 变为 "8"。

注意 "0" 本身是一个有效的整数,不需要去除。

5.统计不同整数

使用一个集合(Set)来存储所有不同的整数,因为集合自动去重。

遍历所有候选整数,将去前导零后的整数添加到集合中。

6.输出结果

最后,集合的大小即为不同整数的数目。

三.代码实现

在写代码时我遇到了前导零如何去除的问题,因为我用C语言的思想去写Java时,我的代码出现了报错,于是我就求助了豆包自带的AI,最后成功的写出来了。

    public static int solution(String word) {
        // write code here
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < word.length(); i++) {
            if(Character.isDigit(word.charAt(i))){
                s.append(word.charAt(i));
            }else{
                s.append(' ');
            }
        }
        String[] w = s.toString().split("\\s+");
        Set<String> uniqueNumbers = new HashSet<>();        for (String num : w) {
            if (!num.isEmpty()) {
                // 去除前导零
                String trimmedNum = num.replaceFirst("^0+(?!$)", "");
                uniqueNumbers.add(trimmedNum);
            }
        }
        return uniqueNumbers.size();
    }
    

四.时间复杂度

O(n):该算法的时间复杂度主要取决于for循环的循环条件,因此为O(n),n是输入字符串word的长度。

1. 字符串长度(n) :

输入字符串 word 的长度是决定时间复杂度的主要因素。

2 字符检查:

Character.isDigit() 方法用于检查每个字符是否为数字,这是一个常数时间操作 O(1)。

3.字符串拼接:

使用 StringBuilder 的 append() 方法来构建新的字符串,这也是一个常数时间操作 O(1)。

4.字符串分割:

split("\s+") 方法用于将字符串分割成单词数组,其时间复杂度为 O(n)。

5. 去重和存储:

使用 HashSet 来存储不同的整数,add() 操作平均情况下是 O(1),但在最坏情况下可能是 O(n)。

6.正则表达式处理:

正则表达式用于去除前导零,其时间复杂度取决于当前处理的字符串长度,但整体上不会超过 O(n)。

7.循环遍历:

代码中有两个主要的循环:一个用于构建 StringBuilder,另一个用于处理分割后的字符串数组。这两个循环的时间复杂度都是 O(n)。