题目描述
小F和他的朋友们围成一个圈,每个人的背上贴有一个字母,这个字母要么是A,要么是B。游戏规则是从第一个人开始计数,每遇到一个贴着字母A的人就计数一次。当计数到第 (k) 个A时,游戏结束。你的任务是帮助小F计算,在第 (k) 次遇到字母A后停止,他总共需要数多少个人。
解题思路
分析需求
- 输入:三个参数,分别是人数 (n)(即字符串长度),目标次数 (k),以及一个表示人们背上的字母序列的字符串
people。 - 输出:一个整数,表示为了达到第 (k) 次遇到字母A,小F需要数的人数总和。
关键点
- 统计字母A的数量:首先,我们需要知道给定的字符串中字母A出现的次数,因为这将直接影响我们是否需要进行完整的循环。
- 确定完整循环次数:如果 (k) 大于字符串中A的总数,则需要完整地遍历整个字符串若干次,直到 (k) 减少到小于或等于一个完整循环中的A的数量为止。
- 计算剩余部分:在完成所有必要的完整循环之后,可能还需要额外数一些人来达到第 (k) 个A。这部分需要特别处理。
算法步骤
- 初始化:定义变量用于存储字母A的总数
countA,完整循环次数fullCycles,以及剩余需要找到的A的数量remainingA。 - 统计A的数量:遍历字符串
people,统计其中A的数量。 - 计算完整循环次数:根据 (k) 和
countA的关系,计算需要完整遍历字符串的次数,并更新remainingA。 - 计算结果:先加上完整循环的总人数,然后继续遍历字符串,直到找到所需的
remainingA个A。 - 返回结果:最终结果即为需要数的人数总和。
代码解析
public class Main {
public static int solution(int n, int k, String people) {
// 统计字符串中A的总数
int countA = 0;
for (char c : people.toCharArray()) {
if (c == 'A') countA++;
}
// 如果k大于字符串中A的个数,需要完整循环几次
int fullCycles = (k - 1) / countA;
int remainingA = k - fullCycles * countA;
// 计算完整循环的长度
int result = fullCycles * n;
// 计算剩余部分需要的长度
if (remainingA > 0) {
int count = 0;
for (int i = 0; i < n; i++) {
result++;
if (people.charAt(i) == 'A') {
count++;
if (count == remainingA) {
break;
}
}
}
}
return result;
}
public static void main(String[] args) {
System.out.println(solution(3, 3, "AAB") == 4);
System.out.println(solution(3, 3, "BBA") == 9);
System.out.println(solution(5, 4, "ABABA") == 6);
}
}
- 统计字母A的数量:通过遍历字符串并使用条件判断来实现。
- 计算完整循环次数:利用数学运算快速计算。
- 处理剩余部分:再次遍历字符串,但这次只遍历至找到所需的A数量即可。
学习心得
1. 理解问题的本质
在解决这个问题时,首先要理解问题的本质,即我们需要找到第 (k) 个字母A的位置。通过将问题分解为两个部分:完整循环和剩余部分,可以使问题变得更加清晰和容易解决。
2. 预处理的重要性
预处理数据可以显著提高算法的效率。在这个问题中,通过预先统计字符串中字母A的数量,我们可以快速计算出需要完整循环的次数,从而减少不必要的计算。
3. 循环和条件判断的结合
循环和条件判断是编程中非常常见的操作。在这个问题中,我们使用了两个循环:一个用于统计字母A的数量,另一个用于寻找剩余部分的字母A。合理地结合循环和条件判断,可以使代码更加简洁和高效。
4. 数学运算的应用
数学运算是解决这类问题的关键。通过简单的数学运算,我们可以快速计算出完整循环的次数和剩余部分需要的字母A数量。这不仅提高了算法的效率,也使得代码更加易读和维护。
5. 测试用例的重要性
编写测试用例可以帮助我们验证算法的正确性。在这个问题中,我们提供了几个典型的测试用例,确保我们的算法能够处理各种边界情况。通过这些测试用例,我们可以及时发现和修复潜在的问题。
总结
通过解决这个问题,我深刻体会到了算法设计的重要性。合理的算法设计不仅可以提高程序的效率,还可以使代码更加清晰和易于维护。同时,我也学会了如何通过预处理数据和数学运算来优化算法,这对于解决复杂问题非常有帮助。在未来的学习和工作中,我会继续努力提升自己的算法能力,以应对更多挑战。