前提:本人是java小白
题目:不同整数的计数问题
小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) 遍历输入字符串
word,将所有非数字字符替换为空格。(2) 这可以通过遍历字符串并使用
StringBuilder来实现。 -
提取整数:
(1) 使用
split()方法将替换后的字符串按空白字符分割成多个部分。(2) 过滤掉空的部分,并去除每个部分的前导零。
-
统计不同整数的数量:
(3) 使用
HashSet来存储这些整数字符串,自动去重。(4) 返回
HashSet的大小,即不同整数的数量。
以样例1为例,具体思路过程如下
第一步:替换非数字字符
假设输入字符串为 "a123bc34d8ef34"
| 字符 | 是否为数字 | stb |
|---|---|---|
| a | 否 | |
| 1 | 是 | 1 |
| 2 | 是 | 12 |
| 3 | 是 | 123 |
| b | 否 | 123 |
| c | 否 | 123 |
| 3 | 是 | 123 3 |
| 4 | 是 | 123 34 |
| d | 否 | 123 34 |
| 8 | 是 | 123 34 8 |
| e | 否 | 123 34 8 |
| f | 否 | 123 34 8 |
| 3 | 是 | 123 34 8 3 |
| 4 | 是 | 123 34 8 34 |
最终得到的 stb 为 "123 34 8 34 "(注:stb为修正后的字符串)。
第二步:提取整数并去除前导零
-
分割字符串:
String[] parts = modifiedWord.toString().split("\s+");结果:
parts = ["123", "34", "8", "34"] -
处理每个部分:
(1) 将每个部分转换为整数再转换回字符串以去除前导零。
(2) 使用
HashSet存储这些整数字符串。
| 部分 | 转换 | HashSet 中的内容 |
|---|---|---|
| 123 | 123 | {"123"} |
| 34 | 34 | {"123", "34"} |
| 8 | 8 | {"123", "34", "8"} |
| 34 | 34 | {"123", "34", "8"} |
最终 HashSet 中的内容为 {"123", "34", "8"}。
第三步:返回不同整数的数量
return distinctIntegers.size();
结果:3
具体代码
import java.util.*;
class Main {
public static int solution(String word) {
StringBuilder stb = new StringBuilder();
for (char c : word.toCharArray()) {
if (Character.isDigit(c)) {
stb.append(c); // 如果是数字字符,则追加到stb中
} else {
stb.append(' '); // 如果是非数字字符,则追加一个空格
}
}
Set<String> hs = new HashSet<>();
String[] parts = stb.toString().split("\\s+"); // 使用正则表达式按空白字符分割字符串
for (String part : parts) {
if (!part.isEmpty()) { // 确保部分不为空
String trimmedPart = Integer.parseInt(part) + ""; // 去除前导零
hs.add(trimmedPart); // 将转换后的字符串添加到集合中
}
}
return hs.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);
}
}
知识点总结
1. StringBuilder
-
含义:
StringBuilder是一个可变的字符序列,用于高效地构建字符串。 -
优点: 相比于
String的不可变性,StringBuilder提供了更高的性能,特别是在需要频繁修改字符串的情况下。
2. Character.isDigit()
-
含义:
Character.isDigit(char ch)方法用于判断一个字符是否是数字。 -
返回值:boolean类型,如果字符是数字('0' 到 '9'),返回
true;否则返回false。
3. String.split() 和 正则表达式
-
含义:
String.split(String regex)方法根据给定的正则表达式将字符串分割成子字符串数组。 -
正则表达式:
\s+: 匹配一个或多个空白字符(包括空格、制表符等)。
4. HashSet
-
含义:
HashSet是一个基于哈希表实现的集合,不允许重复元素。 -
特点:
(1) 不保证元素的顺序。
(2) 添加和查找操作的时间复杂度接近 O(1)。
5. 集合去重
-
作用: 使用集合(如
HashSet)来自动去除重复的元素。 -
原理:
(1)
HashSet内部使用哈希表存储元素,每个元素在插入时都会计算其哈希码(2) 如果两个元素的哈希码相同且通过
equals方法比较也相等,则认为它们是重复的,不会被再次插入。
学习建议
建议大家在学习java时,理解学习常用的集合框架及其特性。然后就是多写代码,尤其是涉及到字符串处理和集合操作的题目,多练习就能记住的更牢固。在完成一道题后,回顾并思考是否有更好的解决方案。分析自己代码的优点和不足,并尝试优化。而且也要学会使用AI。