约瑟夫问题之简单实现

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。
例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。

下面是我的实现代码及实现思路。

import java.util.ArrayList;
import java.util.List;

public class My_JOSEF {
	
	/**
	 * 
	 * 分析:
	 * 1、先根据具体人数生成一个List,并且每个值代表某人的编号。
	 * 2、计算将杀之人的index,将杀到的人移除出List。
	 * 3、最终结果是全部人死亡,所以循环List的长度次数2步骤杀人。
	 * 
	 */
	
	public static final int N = 6; //定义人数
	public static final int M = 5; //定义第M个人被杀
	
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		for(int i=1; i<=N; i++){
			list.add(String.valueOf(i));
		}
		long begin = System.currentTimeMillis();
		kill(list, M);
		long end = System.currentTimeMillis();
		System.out.println("My_JOSEF 此次任务所消耗毫秒数:" + (end - begin));
	}
	
	public static void kill(List<String> list, int M){
		int size = list.size();
		int index = 0;
		for(int i=0; i<size; i++){
			if((index + M) >= list.size()){
				index = (index + M - 1) % list.size();
			}else{
				index = index + M - 1;
			}
			System.out.println("本轮被杀的人是 "+ (list.get(index)) +" 号");
			list.remove(index);
			index = index == list.size() ? 0 : index;
		}
	}

}
 
 


后面我又去百度百科查了下,根据百度百科的分析也尝试着实现了一下。

public class JOSEF_Demo {

	/**
	 * 
		分析:
		(1)由于对于每个人只有死和活两种状态,因此可以用布朗型数组标记每个人的状态,可用true表示死,false表示活。
		(2)开始时每个人都是活的,所以数组初值全部赋为false。
		(3)模拟杀人过程,直到所有人都被杀死为止。
		*提示:该分析复制自百度百科 约瑟夫问题!
	 *
	 */
	
	public static final int N = 6; //定义人数
	public static final int M = 5; //定义第M个人被杀
	
	public static void main(String[] args) {
		boolean[] arrs = new boolean[N];
		long begin = System.currentTimeMillis();
		kill(arrs, 0);
		long end = System.currentTimeMillis();
		System.out.println("JOSEF_Demo 此次任务所消耗毫秒数:" + (end - begin));
	}
	
	public static void kill(boolean[] arrs, int index){
		for(int i = 0; i < arrs.length; i++){
			int n = 0;
			while(n < M){
				if(!arrs[index]){
					n++;
				}
				if(n != M){
					index = (index == arrs.length - 1)? 0 : ++index;
				}
			}
			arrs[index] = true;
			System.out.println("本轮被杀的人是 "+ (index+1) +" 号");
		}
	}
}


总结:

两种实现方法在人数基数为6的时候,基本上都是0毫秒,1毫秒就能解决,相差不大,然后我把人数基数调到100万后,执行效率就很明显了,我自己的思路实现的代码花了大概60000ms,而根据百度百科的思路去实现的只用了14000ms多。另外值得一提的是在我实现的方式中,因为听说LinkedList在增删比较多情况下,会比ArrayList快,所以我尝试着把ArrayList换成LinkedList,花了几分钟都没跑完。这不得不让我重新再去研究下什么时候才适合使用LinkedList了呀。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值