问题描述
小R有一个字符串 word,该字符串由数字和小写英文字母组成。小R想用空格替换每一个不是数字的字符。然后,他希望统计在替换后剩下的整数中,不同整数的数目。
例如,给定字符串 "a123bc34d8ef34",替换后形成的字符串是 " 123 34 8 34",剩下的整数是 "123"、"34"、"8" 和 "34"。不同的整数有三个,即 "123"、"34" 和 "8"。
注意,只有当两个整数的不含前导零的十进制表示不同,才认为它们是不同的整数。
算法选择
hashset + 滑动窗口
算法思路
-
初始化:
- 创建一个
Set<Character>集合,用于存储所有的小写英文字母。 - 创建一个
Set<Integer>集合,用于存储不同的整数。
- 创建一个
-
遍历字符串:
- 使用两个指针
l和r分别表示当前遍历的起始位置和结束位置。 - 遍历字符串
word,使用r指针。
- 使用两个指针
-
处理字符:
-
如果当前字符
cs[r]是小写字母(即在set集合中),则将l指针向前移动,表示忽略这个字符。 -
如果当前字符不是小写字母(即数字),则开始收集数字:
- 继续向后移动
r指针,直到遇到下一个非数字字符或到达字符串末尾。 - 使用
Integer.parseInt将从l到r的子字符串转换为整数,并添加到ans集合中。 - 更新
l指针为当前r的位置,准备下一次数字的收集。
- 继续向后移动
-
-
返回结果:
- 遍历结束后,
ans集合中存储的就是所有不同的整数。 - 返回
ans集合的大小,即不同整数的数目。
- 遍历结束后,
代码展示
import java.util.HashSet;
import java.util.Set;
class Main {
public static int solution(String word) {
// write code here
int l = 0;
int r = 0;
char[] cs = word.toCharArray();
int n = cs.length;
// 创建一个小写字母集合
Set<Character> set = new HashSet<>(26);
for (int i = 0; i < 26; i++) {
set.add((char) ('a' + i));
}
Set<Integer> ans = new HashSet<Integer>();
while (r < n) {
if (set.contains(cs[r])) {
l++;
r++;
} else {
while (r < n && !set.contains(cs[r])) {
r++;
}
// 此时要么r == n, 要么r指向字母
ans.add(Integer.parseInt(word.substring(l, r)));
l = r;
}
}
return ans.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);
}
}