问题描述
小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
问题解析:
目标:
给定一个包含数字和字母的字符串,统计其中不同整数的数量。
关键点:
- 非数字字符替换为空格:
将所有字母替换为空格,使整数分隔开。 - 去除前导零:
比较时,忽略数字前导零。例如,"01" 和 "1" 视为相同。 - 不同整数统计:
使用一个集合(Set)存储每个整数,自动去除重复。
解析步骤:
- 替换非数字字符:
使用正则表达式将所有非数字字符替换为空格。 - 分割字符串:
将处理后的字符串按空格分割,提取所有整数。 - 处理前导零:
将每个整数去除前导零后存入集合(Set)中。 - 统计集合大小:
集合中元素的个数即为不同整数的数量。
代码实现:
import java.util.HashSet;
import java.util.Set;
public static int solution(String word) {
// 将所有非数字字符替换为空格
String replaced = word.replaceAll("[^0-9]", " ");
// 按空格分割字符串,得到数字数组
String[] numbers = replaced.trim().split("\s+");
// 使用 HashSet 去重
Set<String> uniqueNumbers = new HashSet<>();
for (String num : numbers) {
if (!num.isEmpty()) {
// 去除前导零
uniqueNumbers.add(num.replaceAll("^0+", ""));
}
}
return uniqueNumbers.size();
}
代码详解:
-
字符串处理:
replaceAll("[^0-9]", " "):将所有非数字字符替换为空格。- 例如:"a123bc34d8ef34" → " 123 34 8 34"。
-
分割字符串:
split("\s+"):按空格分割字符串,得到数字数组。trim():去除首尾空格,防止数组中出现空字符串。
-
去除前导零:
replaceAll("^0+", ""):去除每个数字的前导零。- 如果数字全是零,例如 "000",则转换为 "",处理空字符串。
-
使用集合去重:
Set<String> uniqueNumbers = new HashSet<>():存储去重后的数字。- HashSet 具有自动去重功能,因此相同数字不会重复存储。
时间复杂度和空间复杂度:
-
时间复杂度:
- O(n) ,其中
n是字符串的长度。 - 遍历字符串和分割字符串的操作都是线性时间。
- O(n) ,其中
-
空间复杂度:
- O(m) ,其中
m是不同整数的数量。 - 使用集合存储
m个不同的整数。
- O(m) ,其中
学习计划:
- 学习如何使用正则表达式进行字符串处理。
- 利用 豆包AI 解析功能,增加对正则表达式的掌握。
工具运用:
-
在豆包MarsCode 上进行多组测试,验证代码的正确性。
-
结合 Java 文档和正则表达式工具,深入理解正则表达式的使用。