一文读懂约瑟夫环算法 | 原力计划
作者 | 扬帆向海
责编 | 王晓曼
出品 | CSDN博客
问题描述
约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。又称“丢手绢问题”)
据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
然而Josephus 和他的朋友并不想遵从。
首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。
问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
问题分析
这个问题可以这样来看,有N个人围成一圈,第一个人从1开始报数,报到3的出圈被杀掉;下一个人接着从1开始报数……这样循环反复,直到剩下最后两个人,求出最后两个人的位置。
实现逻辑
1. 构建一个单向循环链表(链表的尾部指向开头)
① 首先创建循环链表的头节点,让head指向该节点,并形成环形;
② 之后每当创建一个新的节点,就把该节点添加到已有的环形链表中。
2. 遍历单向的循环链表
在此遍历中,当有节点被删除以后,就要向后移动节点。
注意:
当当前节点的值等于当前节点的下一个节点的值的时候,循环结束!
代码实现
package com.study.algorithm;import java.util.Scanner;/*** @Description: 使用循环链表解决约瑟夫环问题* @Author: 扬帆向海* @Date: Created in 2020/5/2*/
public class JosephCircle {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("请输入总人数N(N>=2):");int n = scanner.nextInt();if (n < 2) {System.out.println("您好!请确保输入的人数大于等于 2");return;}// 构建链表并获取头节点,把头节点赋值给currentNodeNode currentNode = buildData(n);// 用来计数int count = 0;// 循环链表当前节点的上一个节点Node beforeNode = null;// 遍历循环链表while (currentNode != currentNode.next) {count++;if (count == 3) {// 向后移动节点beforeNode.next = currentNode.next;System.out.println("出环的编号是: " + currentNode.data);count = 0;currentNode = currentNode.next;} else { // 向后移动节点beforeNode = currentNode;currentNode = currentNode.next;}// 表示只有两个节点了,不再进行出环操作if (beforeNode.data == currentNode.next.data) {break;// 跳出循环}}// 输出最后留在环中的编号System.out.println("最后留在环中的编号是: " + currentNode.data + "," + currentNode.next.data);}/*** 构建单向循环链表** @param n 人数* @return 返回头节点*/private static Node buildData(int n) {// 循环链表的头节点Node head = null;// 循环链表当前节点的前一个节点Node prev = null;for (int i = 1; i <= n; i++) {Node newNode = new Node(i);// 如果是第一个节点if (i == 1) {head = newNode;prev = head;// 跳出当前循环,进行下一次循环continue;}// 如果不是第一个节点prev.next = newNode;prev = newNode;// 如果是最后一个节点if (i == n) {prev.next = head;}}return head;}
}/*** 链表节点*/
class Node {// 当前存储的数据int data;// 当前节点的下一个节点Node next;public Node(int data) {this.data = data;}
}
测试结果:
请输入总人数:41
出环的编号是: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,31
版权声明:本文为CSDN博主「扬帆向海」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43570367/article/details/105896737
【END】
更多精彩推荐☞前端世界起争端,你是现代 Web 技术体系的坚定捍卫者吗?
☞新基建东风下,开发者这样抓住工业互联网风口!
☞15 岁黑进系统,发挑衅邮件意外获 Offer,不惑之年捐出全部财产,Twitter CEO 太牛了!
☞避坑!使用 Kubernetes 最易犯的 10 个错误
☞必读!53个Python经典面试题详解
☞赠书 | 1月以来 Tether 增发47亿 USDT,美元都去哪儿了?
你点的每个“在看”,我都认真当成了喜欢
一文读懂约瑟夫环算法 | 原力计划相关推荐
- 一文读懂约瑟夫环算法
2020-05-25 20:13:40 作者 | 扬帆向海 责编 | 王晓曼 出品 | CSDN博客 问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的 ...
- 一文读懂 KMP 算法 | 原力计划
作者 | 落阳学编程 责编 | 王晓曼 出品 | CSDN 博客 前言 近日被朋友问到了字符串匹配算法,让我想起了大二上学期在一次校级编程竞赛中我碰到同样的问题时,为自己写出了暴力匹配算法而沾沾自喜的 ...
- 一文读懂程序化交易算法交易量化投资高频交易统计利
转 一文读懂程序化交易.算法交易.量化投资.高频交易. 统计套利 在央行发布的<中国金融稳定报告(2016)>中,对于高频交易的解释为程序化交易的频率超过一定程度,就成为高频交易.而对程序 ...
- 一文带你弄懂 Java 动态代理 | 原力计划
作者 | mjzuo 责编 | 王晓曼 出品 | CSDN 博客 在说动态代理之前,先来简单看下代理模式. 代理是最基本的设计模式之一.它能够插入一个用来替代"实际"对象的&quo ...
- k均值聚类算法考试例题_一文读懂K-means聚类算法
1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...
- k means聚类算法_一文读懂K-means聚类算法
1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...
- pca降维的基本思想_一文读懂 PCA 降维算法
转自:chenbjin https://www.cnblogs.com/chenbjin/p/4200790.html 主成分分析(PCA)是一种基于变量协方差矩阵对数据进行压缩降维.去噪的有效方法, ...
- 一文读懂锁相环基本原理
1.锁相环是什么? 锁相环电路是使一个特殊系统跟踪另外一个系统,更确切的说是一种输出信号在频率和相位上能够与输入参考信号同步的电路,它是模拟及数模混合电路中的一个基本的而且是非常重要的模块. 2.锁相 ...
- 一文读懂朴素贝叶斯分类算法
因为毕业论文是和贝叶斯理论相关的内容,今天恰巧看到一篇朴素贝叶斯分类算法的文章,写的非常通俗易懂,再结合另外一篇CNN的文章,在这里梳理一下,来帮助自己的理解. 朴素贝叶斯算法是基于朴素贝叶斯定理的一 ...
最新文章
- 布隆过滤器 redis_使用基于 Redis 的 Java 布隆过滤器
- pytorch中LambdaLR的作用
- Cisco 3560 丢失 IOS 解决过程
- Android深度探索(卷1)HAL与驱动开发读后感---第四章
- Mongodb实战使用指南
- 漫画:什么是HashMap
- Numpy Chararray对象
- Python中的open和codecs.open
- 使用Configuration Manager部署及管理软件更新(1)
- 线性表(插入/清除数据/快慢指针查找中间数据)
- 主板电源开关接口图解_主板跳线接法示意图,超详细适合DIY新手
- Mysql 时间转换 时间函数
- 做APP,从头到尾产品经理需要做什么?- 项目启动前
- Rosalind第16题——ros_bio16_MPRT
- gnu stubs arch linux,编译Nachos源代码时出错“gnu/stubs-32.h:没有这样的文件或目录”...
- 基于ML或DL的iot ddos detection 文献整理
- SATA学习笔记 14 ---SATA PM
- 诺,你们要的Python进阶来咯!我还没见过比这全面的!
- 工具:通过Python fitz 提取PDF内的图片
- 【调研】国内芯片公司对于存算一体芯片的相关调研
热门文章
- 梯度提升树(GBDT)原理小结(转载)
- IOS开发-关于自定义TabBar条
- 本地搭建dubbo实例
- hadoop-2.5安装与配置
- 年度回忆录(2011.07----2011.12)
- sklearn训练模型、保存模型文件(文本、pkl)、模型文件转换(pkl2onnx)以及模型可视化
- [SSH] 设置密钥登陆
- An SSH installation couldn‘t be found
- php中svn上传项目直接访问不了,phpstorm8 通过svn导入项目后项目右键列表里没有subversion选项,无法提交和更新啊?...
- 【word使用技巧】删掉某一行参考