之前在做ACM的时候发现了这个著名的约瑟夫环问题,并且自己自己思考,理解之后发表了这篇博客:
http://blog.csdn.net/quentain/article/details/50081539
今天再次遇到这个题目自己编程练习了下,思路就是两种,一种是环形链表,再一个就是数学归纳总结的递归式子,感觉还是蛮有意思的题目。
题目描述
每年六一儿童节,NowCoder都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为NowCoder的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到NowCoder名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?
在线代码:
import java.util.LinkedList;
import java.util.List;
public class Solution {
public int LastRemaining_Solution(int n, int m) {
//本题初步的第一次的解法即就是基于环形链表
//边界判断
/* if(n<1||m<1){
return -1;
}
List<Integer> list=new LinkedList<>();
//先模拟一个n的环形链表
for(int i=0;i<n;i++){
list.add(i);
}
//要删除元素的位置
int target=0;
//开始循环的删除第target个位置的人
while(list.size()>1){
//分析要删除第m个人,必须移动m-1个位置
for(int i=0;i<m-1;i++){//粗心大意的将i从0开始,移动m-1应该是0到m-2或者1到m-1
target=(target+1)%list.size();//移动m-1次之后即就是删除了第m个元素
}
list.remove(target);
}
return list.get(0);*/
//第二种解法即就是数学归纳总结的递归式子
if (n < 1 || m < 1) {
return -1;
}
int last = 0;
for (int i = 2; i <=n ; i++) {
last = (last + m)%i;
}
return last;
}
}