✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: 华为OD机试攻略:Java实现并讲解2022&2023真题
文章目录
- 1. 题目描述
- 2. 输入描述
- 3. 输出描述
- 4. Java算法源码
- 5. 测试
- 6.解题思路
1. 题目描述
给定由[a-z] 26个英文小写字母组成的字符串A和B,其中A中可能存在重复字母,B中不会存在重复字母。现从字符串A中按规则挑选一些字母,以组成字符串B。
挑选规则如下:
- 同一个位置的字母只能被挑选一次;
- 被挑选字母的相对先后顺序不能改变。
求最多可以同时从A中挑选多少组能组成B的字符串。
2. 输入描述
输入为2行,第1行输入字符串A,第2行输入字符串B。行首行尾无多余空格,其中A和B均由[a-z] 26个英文小写字母组成。
- 0 < A.length < 100,A中可能包含重复字母。
- 0 < B.length < 10,B中不会出现重复字母。
3. 输出描述
输出1行,包含1个数字,表示最多可以同时从A中挑选多少组能组成B的字符串,行末无多余空格。 无需验证输入格式和输入数据合法性。
4. Java算法源码
/**
* 从字符串A中按规则挑选一些字母,组成字符串B。
*
* 同一个位置的字母只能被挑选一次;
* 被挑选字母的相对先后顺序不能改变;
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 可能存在重复字母的字符串A
String a = sc.nextLine();
// 不存在重复字母的字符串B
String b = sc.nextLine();
char[] arrA = a.toCharArray();
char[] arrB = b.toCharArray();
int count = 0;
int i = 0;
int j = 0;
while (i < a.length()) {
if (arrA[i] == arrB[j]) {
// 已经匹配的置为*,表示无法复用
arrA[i] = '*';
// 能匹配对应的字符,子串指针后移
j++;
}
// 如果j到达尾部+1了,则重新置0
if (j == b.length()) {
i = 0;
j = 0;
count++;
} else {
i++;
}
}
System.out.println(count);
}
5. 测试
示例输入 | 示例输出 | 说明 |
---|---|---|
abcabc | abc | 按照顺序,从字符串A中取出两个B。 |
javajjnezharrr jar | 2 | 从字符串A中依次取出"jar",可以取两次。 |
6.解题思路
- 将字符串A和字符串B转换为字符数组
arrA
和arrB
。 - 初始化计数变量
count
为0,表示可以同时从A中挑选的组数。 - 使用两个指针
i
和j
分别指向arrA
和arrB
的起始位置。 - 开始遍历
arrA
,当指针i
小于A
的长度时,执行以下操作:- 检查
arrA[i]
和arrB[j]
是否相等。如果相等,说明可以从A中挑选该位置的字母用于构造B,因此将arrA[i]
置为'*'
表示已经使用过。 - 将指针
j
后移一位,继续比较下一个位置的字母。 - 如果指针
j
达到B
的末尾,说明已经成功匹配了一个B,此时将计数变量count
加1,并将指针i
和j
重新置为0,以便继续寻找下一个匹配。 - 如果指针
j
未达到B
的末尾,说明当前位置的字母无法匹配,继续将指针i
后移一位,继续寻找下一个可能的匹配。
- 检查
- 循环结束后,输出计数变量
count
,即为最多可以同时从A中挑选的组数。
通过上述算法,我们可以有效地计算出最多可以同时从A中挑选多少组能够组成B的字符串。