约瑟夫环问题链表实现(Java)

约瑟夫环问题链表实现(Java)面试中可能经常会遇到约瑟夫环问题,逻辑上很简单,就是看怎么实现了,一般而言,最简单最直观的就是利用链表,然后构建一个循环结构,正好是环,最后计算出结果。遍历环形链表会是一个无限循环,如果链表中的数据逐渐减少,不控制终究会一个不剩,这又不满足我们问题的求解,因此我们需要定义出循环结束的条件,按照约瑟夫环的规则,只剩下一个的时候就结束,在环形链表结构中,那就是结点本身的下一个节点就…

大家好,又见面了,我是你们的朋友全栈君。

    面试中可能经常会遇到约瑟夫环问题,逻辑上很简单,就是看怎么实现了,一般而言,最简单最直观的就是利用链表,然后构建一个循环结构,正好是环,最后计算出结果。

    遍历环形链表会是一个无限循环,如果链表中的数据逐渐减少,不控制终究会一个不剩,这又不满足我们问题的求解,因此我们需要定义出循环结束的条件,按照约瑟夫环的规则,只剩下一个的时候就结束,在环形链表结构中,那就是结点本身的下一个节点就是它自己。这样就可以结束遍历了。最后打印出剩下的结点,问题解决。

这里给出Java版本的实现:

package com.xxx.algorithm.wh;
//约瑟夫环java实现
//约瑟夫环问题的起源来自犹太历史学家约瑟夫和他的朋友以及39其余的犹太人,总共41人为了躲避敌人,藏在一个山洞中,
//39个犹太人决定宁愿死也不被敌人抓到,于是决定自杀,所有人排成一个圈,由第一个人开始报数,每当数到3,就自杀。
//这个游戏接着从自杀的位置开始,还是从1数到3。依次类推,约瑟夫将朋友和自己安排在了16和31的位置,最后顺利逃过了
//自杀这一劫,因为最后就剩他一个人了。
public class JosefCircleMain {
	
	public static void count(int n){
		//数到3出局,中间间隔两个人
		int k = 3;
		//头结点不存储数据
		Node head = new Node();
		Node cur = head;
		//循环构造这个链表
		for(int i=1;i<=n;i++){
			Node node = new Node(i);
			cur.next = node;
			cur = node;
		}
		//链表有数据的部分首尾相连形成一个环。
		cur.next = head.next;
		//统计开始的时候,刨去头结点,然后从第一个有数据的结点开始报数
		Node p = head.next;
		//循环退出的条件是最后只剩一个结点,也就是这个结点的下一个结点是它本身
		while(p.next!=p){
			//正常报数的遍历逻辑
			for(int i=1;i<k-1;i++){
				p = p.next;
			}
			//当数到3的时候,出局
			System.out.print(p.next.data+"->");
			p.next = p.next.next;
			p = p.next;
		}
		//最后剩下的一个结点
		System.out.println("(left:"+p.data+")");
	}

	public static void main(String[] args) {
		//以4个人为例,1234 : 最先出局的是3,然后剩下412,接着2出局,剩下41,这时候就是4出局,最后剩下1.
		count(4);
		//41个人为例,就是约瑟夫环的本身了,最后剩下的是31
		count(41);
	}

}

class Node{
	int data;
	Node next;
	public Node(){}
	public Node(int data){this.data = data;}
}

    一般的链表,如果没有特别的说明,头结点是有数据的,但是这里情况比较特殊,我们构建了一个头结点没有数据的空节点,然后将链表的首尾相连,这个首其实也不是头结点,而是头结点的下一个结点,用图表示就是如下:

约瑟夫环问题链表实现(Java)

    首次遍历的时候,我们是从1开始的,所以代码中有这样的一句:

约瑟夫环问题链表实现(Java)

运行程序,打印结果:

3->2->4->(left:1)
3->6->9->12->15->18->21->24->27->30->33->36->39->1->5->10->14->19->23->28->32->37->41->7->13->20->26->34->40->8->17->29->38->11->25->2->22->4->35->16->(left:31)

打印结果既验证了只有4个结点的情况,也验证了约瑟夫环的本身的结论。 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136160.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java实现单链表、栈、队列三种数据结构

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 作者:远航 cnblogs.com/yang-guang-zhang/p/13884023.html 一、单链表 1…

    2021年6月26日
    115
  • task scheduler什么意思_女贞子的功效与作用

    task scheduler什么意思_女贞子的功效与作用前言本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!本专栏目录结构和参考文献请见1000个问题搞定大数据技术体系正文TaskScheduler的核心任务是提交TaskSet到集群运算并汇报结果。(1)为TaskSet创建和维护一个TaskSetManager,并追踪任务的本地性以及错误信息。(2)遇到Straggle任务时,会放到其他节点进行重试。(3)向DAGScheduler

    2022年10月11日
    7
  • 车用总线技术 | J1939协议实用指南与J1939数据记录方案

    车用总线技术 | J1939协议实用指南与J1939数据记录方案“没错,这是一份SAEJ1939协议的简单、实用指南。”—虹科开篇:在这篇介绍中,我们介绍了J1939协议的基本知识,其中包括PGN和SPN。因为这是一篇偏向应用的简介,所以您还将会学习到如何通过DBC文件解码J1939数据、如何记录J1939、典型的应用案例和实用技巧。下面,来了解下这份简单易懂的J1939介绍吧~什么是J1939?J1939简介简而言之,SAEJ1939其实是一套标准,重型车辆ECU间就是按照这套标准在CAN总线上进行通信的。当今大多数车辆都通过CAN(Con…

    2022年5月1日
    651
  • H5音乐标签实现网页自动播放和隐藏

    H5音乐标签实现网页自动播放和隐藏网页播放音乐如果不能自动播放,用iframe放在body最下面。即可运行。<iframesrc=”no.mp3″allow=”autoplay”hidden/>

    2022年7月25日
    21
  • html嵌入python代码(python做人脸识别)

    最近闲来无事,研究研究在安卓上跑Python。想起以前玩过的kivy技术,kivy[1]是一个跨平台的UI框架。当然对我们最有用的是,kivy可以把python代码打包成安卓App。但是由于安卓打包的工具链很长,包括androidsdk打包java代码、ndk编译python、编译各种python依赖包,经常花一整天从入门到放弃。这次使出认真研究的心态,终于找到一个解决方案,于是有了这篇文章:…

    2022年4月16日
    136
  • WebPack_钢铁雄心4toolpack

    WebPack_钢铁雄心4toolpack关于Devtool该选项控制是否以及如何生成源映射。官网上给出的可选值有:其中一些值适合开发,一些用于生产。对于开发,您通常需要快速的SourceMaps,以bundle的大小为代价,但是对于生产,您需要独立的SourceMaps,这是精确的,并且支持最小化。选择一种源映射样式,以增强调试过程。这些值可以显著地影响构建和重建速度。而不是使用devtool选项还可以使用Sourc…

    2022年10月5日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号