题目描述
有10个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
示例
最后剩下的是4号
序号 0 1 2 3 4 5 6 7 8 9
人名 1 2 3 4 5 6 7 8 9 0
报数 1 2 - 1 2 - 1 2 - 1
报数 2 - 1 2 - 1 2
报数 - 1 2 - 1
报数 2 - 1
报数 2 -
解题思路
1.设置每个人的初始状态为都在圈内,为true
。如果报到3就被踢出圈,,为false
。
2.10个人得成环。用 index= (index + 1)% 人数
得到每个人的下标,例如第10个人,下标为9,则它的index
= 0。
类似于循环队列问题:https://blog.csdn.net/qq_43777322/article/details/89441884
3.每三个人是一个轮回,报的3 的人退出。用count
表示每个人报的数,count =(count+1)%3
。
4.一直到只剩一个人时,循环结束。
5.找到那个状态还为true
的人,输出他。
实现代码
测试用例
public static void main(String[] args) {
System.out.println(callSurvivalNumber(10));
System.out.println(callSurvivalNumber(1));
System.out.println(callSurvivalNumber(0));
System.out.println(callSurvivalNumber(-1));
}
具体方法
/**
* @param count The total number of people in a circle
* @return the last person
*/
public static int callSurvivalNumber(int count) {
//1.校验合法性
if (count <= 0) {
throw new UnsupportedOperationException("can't into a circle");
}
//2.创建一个数目为count的boolean[],设置初始状态true,表明每个人都在圈里
boolean[] peopleStates = new boolean[count];
for (int i = 0; i < peopleStates.length; i++) {
peopleStates[i] = true;
}
int index = -1;
int counter = 0; //退出圈子的人数
int current = 0; //当前人报的数
while(counter < peopleStates.length - 1) {
//3.先让其成环
index = (index + 1) % peopleStates.length;
//如果这个人已经退圈,就跳过他走向下一个人
if (peopleStates[index] == false) {
continue;
}
//4.index报的数为
current = (current +1) % 3;
if (current == 0) {
peopleStates[index] = false;
counter++;
}
}
int i = 0;
for (; i < peopleStates.length; i++) {
if (peopleStates[i] == true) {
return i+1;
}
}
throw new RuntimeException("not found");
}