4.约瑟夫问题

问题:

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));
	}
}

猜你喜欢

转载自blog.csdn.net/qq_38442065/article/details/80564372