java约瑟夫环逻辑_约瑟夫环Java实现

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

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

这里给出Java版本的实现:

//约瑟夫环java实现

//约瑟夫环问题的起源来自犹太历史学家约瑟夫和他的朋友以及39其余的犹太人,总共41人为了躲避敌人,藏在一个山洞中,39个犹太人决定宁愿死也不被敌人抓到,于是决定自杀,所有人排成一个圈,由第一个人开始报数,每当数到3,就自杀。这个游戏接着从自杀的位置开始,还是从1数到3。依次类推,约瑟夫将朋友和自己安排在了16和31的位置,最后顺利逃过了自杀这一劫,因为最后就剩他朋友了。

package com.nowcoder.community.算法;

/**

* @author 找花插的牛粪

* @apiNote 约瑟夫环

*/

public class 约瑟夫环 {

/**

* 方法入口

*/

public static void getman(int n){

//数到3就自杀

int k=3;

//构建头结点 @prame=null,和他的引用对象

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 begin = head.next;

//循环退出的条件是最后只剩一个结点,也就是这个结点的下一个结点是它本身

while(begin.next != begin){

//开始数数,注意这里只走了K-2步,来分析为什么 1->2->3 ,其实应该走2步,但是for循环再此处走了一步

for (int i = 1; i < k-1; i++) {

begin = begin.next;

}

//是因为我们要办链表除掉一个元素 也就相当于

// 1->2 4 再此处删除了3 然后拼接 4 1->2->4

//所以我们必须拿到 2这个节点,否则不能实现链表元素的删除,谁让咱用的是单链表呢

System.out.println(begin.next.data+"号犹太人"+" go die");

//此时begin为2节点

begin.next = begin.next.next;

begin = begin.next;

}

//最后剩下的一个结点

System.out.println("最后胜出者为:"+begin.data+"号");

}

public static void main(String[] args) {

//以4个人为例

getman(4);

System.out.println("========================");

//以41个人为例 16胜出

getman(41);

}

}

/**

* @author 找花插的牛粪

* @apiNote 构建链表成员

*/

class Node{

int data;

Node next;

public Node(){};

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

}

运行程序,打印结果:

559a16f101181099bc30d6cd4b135b06.png

d6cf4cfec75471c5cb19a13274bae85d.png

标签:Node,begin,Java,实现,结点,next,链表,约瑟夫

来源: https://blog.csdn.net/weixin_41677268/article/details/110726500

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值