一、题目
题目描述
约瑟夫问题是一个著名的趣题。这里我们稍稍修改一下规则。有n个人站成一列。并从头到尾给他们编号,第一个人编号为1。然后从头开始报数,第一轮依次报1,2,1,2...然后报到2的人出局。接着第二轮再从上一轮最后一个报数的人开始依次报1,2,3,1,2,3...报到2,3的人出局。以此类推直到剩下以后一个人。现在需要求的即是这个人的编号。
给定一个int n,代表游戏的人数。请返回最后一个人的编号
测试样例:
5
返回:5
二、分析
以n=10为例
初始:1,2,3,4,5,6,7,8,9,10
第一轮:踢出数到2的人,即2,4,6,8,10,此时剩下1,3,5,7,9
第二轮:从上一轮最后一个9开始,踢出数到2,3的人,应该按照9,1,3,5,7的顺序开始,踢出1,3,7,此时剩下9,5
第三轮:从上一轮最后一个5开始,踢出数到2,3,4的人,按5,9的顺序开始,题出9,此时剩下5
以上变为n=10时,该游戏的过程。
public class YueSeFuWenTi {
public static int getResult(int n) {
LinkedList<Integer> res = new LinkedList<Integer>();
int round = 2, i = 0, curr = 0;
for (i = 1; i <= n; i++) {
res.add(i);//链表初始化
}
while (res.size() > 1) {
i = 0;
while (res.size() > 1 && i < res.size()) {
curr = (curr + 1) % round;
if (curr != 1){//数的不是1便踢出
res.remove(i);
}else{
i++;
}
}
for (Integer integer : res) {
System.out.print(integer+" ");
}
System.out.println();
round++;//从2,3,4递增
curr = 0;
if (res.size() > 1) {
//完成链表中元素的逆序
int last = res.removeLast();//返回链表中最后一个元素
res.addFirst(last);//放到头
}
for (Integer integer : res) {
System.out.print(integer+" ");
}
System.out.println();
}
return res.pop();
}
public static void main(String[] args) {
System.out.println(getResult(10));
}
}
Maybe life will not always show it to my smile, but I have to learn to smile to face every day of my life.