问题描述
小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、结果返回:
返回集合的大小,即不同数字的数量。
复杂度分析
时间复杂度分析
- 字符处理:
-
- 遍历输入字符串的每个字符,时间复杂度为 O(n),其中 n** 是输入字符串的长度。
- 对于每个字符,判断其是否为数字并进行相应的操作(追加到列表或追加下划线),这些操作都是常数时间复杂度 O(1)。
- 字符串分割:
-
- 将列表转换为字符串的操作是 O(n)。
- 使用下划线分割字符串的操作也是 O(n),因为分割操作需要遍历整个字符串。
- 集合存储:
-
- 遍历分割后的字符串数组,时间复杂度为 O(m),其中 m** 是分割后的数组长度。
- 对于每个非空的数字字符串,将其转换为整数并添加到集合中。集合的插入操作平均时间复杂度为 O(1)。
- 因此,这一部分的时间复杂度为 O(m)。
综合以上步骤,总的时间复杂度为: O(n)+O(n)+O(m)=O(n+m)、
由于 m 是分割后的数组长度,最坏情况下 m 也是 O(n),因此总的时间复杂度为 O(n)。
空间复杂度分析
- 字符处理:
-
- 创建一个新的列表
sb来存储处理后的字符,空间复杂度为 O(n)。
- 创建一个新的列表
- 字符串分割:
-
- 将列表转换为字符串,空间复杂度为 O(n)。
- 分割后的数组
split的空间复杂度为 O(n),因为最坏情况下每个字符都是一个单独的子字符串。
- 集合存储:
-
- 创建一个集合
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)