每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
如果没有小朋友,请返回-1
解题思路:别用公式来做,就用简单的数组来进行循环模拟,就可以算出来。
import java.util.*;
public class Solution {
public int LastRemaining_Solution(int n, int m) {
if(n==0 || m == 0)
return -1;
int[] array = new int[n];
int i = -1,step = 0,count = n;
while(count>0){
i++;
if(i>=n) i=0;
if(array[i] == -1) continue;
step++;
if(step == m){
array[i] = -1;
step = 0;
count--;
}
}
return i;
}
}
题目描述:约瑟夫问题进阶
约瑟夫问题是一个著名的趣题。这里我们稍稍修改一下规则。有n个人站成一列。并从头到尾给他们编号,第一个人编号为1。然后从头开始报数,第一轮依次报1,2,1,2...然后报到2的人出局。接着第二轮再从上一轮最后一个报数的人开始依次报1,2,3,1,2,3...报到2,3的人出局。以此类推直到剩下以后一个人。现在需要求的即是这个人的编号。
给定一个int n,代表游戏的人数。请返回最后一个人的编号
测试样例:
5
返回:5
解题思路:用链表进行创建,然后留着最开始的位置,用来存放最后一个元素,因为最后的元素是上一次的最后一个元素。round用来记录每次删除的位置,cur用来进行遍历。
import java.util.*;
public class Joseph {
public int getResult(int n) {
// write code here
if(n<1)
return -1;
LinkedList<Integer> list = new LinkedList<>();
int round = 2,i,curr = 0;
for( i = 1;i<=n;i++){
list.add(i);
}
while(list.size()>1){
i = 0;
while(list.size()>1 && i<list.size()){
curr = (curr+1)%round;
if(curr != 1){
list.remove(i);
}else{
i++;
}
}
curr = 0;
round++;
if(list.size()>1){
int last = list.removeLast();
list.addFirst(last);
}
}
return list.pop();
}
}