有N个程序猿(编号1~n)围成一圈顺序循环报数,
从第一个猿开始报数(从1到4报数,猿都是顺序排列成一圈的),凡报到4的猿退出圈子,以下一个为1继续报数,问最后留下的是原来第几号的那位。
题目的意思大致是这样,比如最开始有五个人编号为1 2 3 4 5
- 第一轮去掉4
- 1 2 3 5
- 第二轮起点是5,去掉3
- 1 2 5
- 第三轮起点是5,去掉5
- 1 2
- 第四轮起点是1,去掉2
- 1
最开始想到用数组来做,思路稍微有点复杂,后来想到这种题最适合用链表来做
这里一共写了链表的递归与非递归算法和数组的非递归算法
1.使用LinkedList的非递归算法
public static int ysfh(int num){
LinkedList<Integer>list=new LinkedList<>();
for (int i = 1; i <=num; i++)list.add(i);
int i=0;
while (num>1){
i=(i+3)%list.size();//从0开始,所以是3
list.remove(i);
num--;
}
return list.peek();
}
2.使用LinedList的递归算法
public static int helper(int n){
LinkedList<Integer>list=new LinkedList<>();
for (int i = 1; i <= n; i++)list.add(i);
return ysfh(0,list);
}
public static int ysfh(int begin,LinkedList<Integer>list){
if(list.size()==1)return list.peek();
int i=(begin+3)%list.size();
list.remove(i);
return ysfh(i,list);
}
3.使用数组的非递归算法
public static int ysfh1(int n){
boolean[]judge=new boolean[n];//初始化为fasle,表示位置上的人没有离开
int begin=0;
while (n>1){
int end=(begin+3)%n;
if(!judge[end])judge[end]=true;
else { //定位到下一个非空缺位置
int i=end+1;
while (judge[i%n])i++;
judge[i]=false;
end=i;
}
begin=end+1;
n--;
}
for (int i = 0; i < judge.length; i++)if(!judge[i])return i+1;
return 0;
}
4.测试
public static void main(String[] args) {
System.out.println("1.使用链表的非递归算法: "+ysfh(5));
System.out.println("2.使用链表的递归算法: "+helper(5));
System.out.println("3.使用数组的非递归算法: "+ysfh1(5));
}
1.使用链表的非递归算法: 1
2.使用链表的递归算法: 1
3.使用数组的非递归算法: 1
总的来说,还是用链表好做一些。