问题:
n个人围成一个圈,每个人分别标注为1、2、...、n,要求从1号从1开始报数,报到k的人出圈,接着下一个人又从1开始报数,如此循环,直到只剩最后一个人时,该人即为胜利者。例如当n=10,m=4时,依次出列的人分别为4、8、2、7、3、10,9、1、6、5,则5号位置的人为胜利者。给定n个人,请你编程计算出最后胜利者标号数。
思路:
定义一个静态方法,使用单链表,因为链表中每一个节点包含索引和数据值,满足题设条件,然后每次将报数为m的人除去,直到剩余最后一个人。
实现:
public static int remove (int n,int m) {
if(n==1) { //只有一个人时返回1
return 1;
}
if(n==0 || m==0) {
return -1;
}
ArrayList<Integer> list = new ArrayList<>();
for(int i=1;i<=n;i++) {//链表中插入序号
list.add(i);
}
int flag = -1;//注意配合下文代码,要设定flag的初值为-1
while(list.size()>1) {//当剩余人数大于1时
flag = (m+flag)%(list.size());//取出要除去的人的索引
//System.out.println(list.get(flag));
list.remove(flag);
flag--;
}
return list.get(0);
}
完整代码:
import java.util.ArrayList;
public class Yuesefu {
public static int remove (int n,int m) {
if(n==1) {
return 1;
}
if(n==0 || m==0) {
return -1;
}
ArrayList<Integer> list = new ArrayList<>();
for(int i=1;i<=n;i++) {
list.add(i);
}
int flag = -1;
while(list.size()>1) {
flag = (m+flag)%(list.size());
//System.out.println(list.get(flag));
list.remove(flag);
flag--;
}
return list.get(0);
}
public static void main(String[] args) {
System.out.println(remove(10,4));
}
}