首页/新闻资讯/正文详情

Golang学习-约瑟夫环问题(Josephus Problem)

发布时间:2026/11/12 4:49:36 来源:云帆数科 栏目:资讯中心
Golang学习-约瑟夫环问题(Josephus Problem)
约瑟夫环问题Josephus Problem一、问题描述约瑟夫环是一个经典的数学与计算机科学问题。其情景如下N 个人围成一圈编号 1~N。从编号 1 开始报数报到 M 的人出列下一位从 1 重新开始报数再报到 M 的人出列……如此循环直到只剩最后一人。求最后幸存者的原始编号。这个问题的历史可以追溯到公元 1 世纪犹太历史学家约瑟夫Flavius Josephus在罗马围攻中与 40 名同胞藏身洞穴他们决定宁可自杀也不做俘虏。约瑟夫通过数学计算站到了幸存位置——他自述的这段经历便成了这个问题的名称。二、三种解法对比解法时间复杂度空间复杂度特点数组模拟法O(n × m)O(n)直观易懂但慢循环链表模拟法O(n × m)O(n)贴合问题本质但同样慢递推公式法O(n)O(1)最优解纯数学推导三、解法一数组模拟法用一个[]int表示还在圈中的人1表示在场0表示已出列。从头到尾循环扫描遇到未出列的人就计数数到 m 时标记出列。3.1 实现思路初始化数组所有位置标记为 1在场遍历数组对在场的人报数报到 m 时标记出列计数器归零当出列人数 n-1 时停止剩下那个就是幸存者3.2 代码packagemainimportfmt// JosephusArray 数组模拟法funcJosephusArray(n,mint)int{ifn0||m0{return-1}alive:make([]bool,n)// true在场fori:rangealive{alive[i]true}count:0// 已出列人数number:0// 报数器idx:0// 当前下标forcountn-1{ifalive[idx]{numberifnumberm{alive[idx]false// 出列number0count}}idx(idx1)%n// 环形绕回}// 找到唯一幸存者fori,a:rangealive{ifa{returni1// 编号从 1 开始}}return-1}funcmain(){fmt.Println(n41, m2:,JosephusArray(41,2))// 19fmt.Println(n8, m5:,JosephusArray(8,5))// 3fmt.Println(n5, m3:,JosephusArray(5,3))// 4}运行结果n41, m2: 19 n8, m5: 3 n5, m3: 4缺点每次循环都要跳过已出列的人时间复杂度为 O(n × m)当 n 和 m 都很大时效率很低。四、解法二循环链表模拟法用循环链表直接模拟围成一圈的场景每报到 m 就删除当前节点天然贴合问题模型。4.1 代码packagemainimportfmttypeCLNodestruct{NointNext*CLNode}// JosephusCircularList 循环链表模拟法funcJosephusCircularList(n,mint)int{ifn0||m0{return-1}// 构建循环链表1 - 2 - ... - n - 1head:CLNode{No:1}cur:headfori:2;in;i{cur.NextCLNode{No:i}curcur.Next}cur.Nexthead// 尾指头形成环// 找到头节点的前驱辅助删除prev:headforprev.Next!head{prevprev.Next}// 开始报数每次报 m 个人就删除forcur.Next!cur{// 直到只剩一个人// 报数 m-1 次当前节点算第1个走 m-1 步到第 m 个fori:1;im;i{prevcur curcur.Next}// 删除 cur 节点prev.Nextcur.Next curcur.Next}returncur.No}funcmain(){fmt.Println(n41, m2:,JosephusCircularList(41,2))// 19fmt.Println(n8, m5:,JosephusCircularList(8,5))// 3fmt.Println(n5, m3:,JosephusCircularList(5,3))// 4}运行结果n41, m2: 19 n8, m5: 3 n5, m3: 4优点模型直观不需要额外的标记数组缺点时间复杂度仍然是 O(n × m)空间复杂度 O(n)五、解法三递推公式法最优解这是约瑟夫问题的数学精华。通过递推关系可以做到 O(n) 时间、O(1) 空间。5.1 推导过程设f(n, m)表示 n 个人、报数为 m 时最后幸存者的编号从 0 开始编号。基本情况当 n 1 时只有一个人幸存者就是 0 号。f(1, m) 0递推当 n 个人中第一个出列的是第 m 个人编号 m-1后剩下 n-1 个人。关键在于这 n-1 个人的编号体系发生了偏移原始编号: 0, 1, 2, ..., m-2, m-1, m, m1, ..., n-1 出列后: m, m1, ..., n-1, 0, 1, ..., m-2 重新编号: 0, 1, ..., n-m-1, n-m, n-m1, ..., n-2从原始编号到新编号的映射关系新编号 (旧编号 - m) % n 旧编号 (新编号 m) % n所以f(n, m) (f(n-1, m) m) % n这就是约瑟夫问题的核心递推公式5.2 从 0 编号到 1 编号上述公式假设编号从 0 开始。如果要从 1 开始编号最终结果加 1 即可result f(n, m) 15.3 代码实现packagemainimportfmt// JosephusRecursive 递归版本可能栈溢出n 大时不推荐funcJosephusRecursive(n,mint)int{ifn1{return0}return(JosephusRecursive(n-1,m)m)%n}// JosephusIterative 迭代版本推荐O(n) 时间 O(1) 空间funcJosephusIterative(n,mint)int{ifn0||m0{return-1}survivor:0// f(1, m) 0fori:2;in;i{survivor(survivorm)%i}returnsurvivor1// 转为 1~n 编号}funcmain(){fmt.Println(n41, m2:,JosephusIterative(41,2))// 19fmt.Println(n8, m5:,JosephusIterative(8,5))// 3fmt.Println(n5, m3:,JosephusIterative(5,3))// 4fmt.Println(n1000000, m3:,JosephusIterative(1000000,3))// 大规模也能秒出}运行结果n41, m2: 19 n8, m5: 3 n5, m3: 4 n1000000, m3: 3744335.4 手动验证递推过程以 n5, m3 为例编号 0~4isurvivor计算10f(1)02(03)%2 1f(2)3(13)%3 1f(3)4(13)%4 0f(4)5(03)%5 3f(5)最终 survivor 3转为 1 编号 4。验证正确六、扩展出列顺序如果不仅要求最后幸存者还要知道每个人的出列顺序递推公式就不够了需要模拟。循环链表法可以轻松记录出列顺序funcJosephusOrder(n,mint)[]int{ifn0||m0{returnnil}// 构建循环链表head:CLNode{No:1}cur:headfori:2;in;i{cur.NextCLNode{No:i}curcur.Next}cur.Nexthead prev:headforprev.Next!head{prevprev.Next}varorder[]intforcur.Next!cur{fori:1;im;i{prevcur curcur.Next}orderappend(order,cur.No)prev.Nextcur.Next curcur.Next}orderappend(order,cur.No)// 最后幸存者returnorder}

相关推荐

IX9104 @ACP#PCIe 交换芯片技术解析
IX9104 @ACP#PCIe 交换芯片技术解析

摘要本地部署 Kimi K3、各类端侧 MoE 大模型时,多 NPU、多存储扩展、多路显示外设会产生大量 PCIe 设备挂载需求,主板原生 PCIe 通道数量有限,原生通道拆分方案存在带宽分配固化、调度延迟高、扩展能力弱等工程问题。IX9104 是一款国产 PCIe … · 2026/10/28 9:16:09

python数据可视化技巧的100个练习 -- 46. 相关矩阵的热力图
python数据可视化技巧的100个练习 -- 46. 相关矩阵的热力图

重要性★★★☆☆ 难度★★☆☆☆ 您是一家零售公司的分析师。您的任务是了解不同销售指标之间的关系。为以下销售数据创建相关矩阵的热力图:总销售额、在线销售额、店内销售额和折扣金额。目标是通过可视化相关性,帮助团队了解这些指标之间的关系。编写 Python 代码来生成… · 2026/11/12 4:49:36

泉盛UV-K5/K6对讲机终极改造指南:解锁10大专业功能
泉盛UV-K5/K6对讲机终极改造指南:解锁10大专业功能

泉盛UV-K5/K6对讲机终极改造指南:解锁10大专业功能 【免费下载链接】uv-k5-firmware-custom 全功能泉盛UV-K5/K6固件 Quansheng UV-K5/K6 Firmware 项目地址: https://gitcode.com/gh_mirrors/uvk5f/uv-k5-firmware-custom 你想让手中的泉盛UV-K5/K6对讲机从… · 2026/10/13 10:19:11

工地太忙根本没时间复习考试?特种高低压电工证报名在哪考全攻略
工地太忙根本没时间复习考试?特种高低压电工证报名在哪考全攻略

工地太忙根本没时间复习考试?特种高低压电工证报名在哪考全攻略 工地太忙根本没时间复习考试,这几乎是每一位一线电工的真实写照。尤其在焦作这样的工程大市,电工岗位需求大、流动性强,很多人在忙于施工的同时,往往忽略了特种高低压电工证的办理或复审。… · 2026/11/12 4:49:07

中级电工证丢失怎么办?网上查询解决异地转证难题
中级电工证丢失怎么办?网上查询解决异地转证难题

中级电工证丢失怎么办?网上查询解决异地转证难题 之前考的证在外省能不能转过来?这是很多在外地打工的老电工最头疼的问题。最近,我在处理一起 中级电工证丢失… · 2026/11/12 4:49:07

关于电工证的文案真实经历告诉你怎么过实操考试
关于电工证的文案真实经历告诉你怎么过实操考试

关于电工证的文案真实经历告诉你怎么过实操考试 实操考试心里没底怕挂科,这是很多报考电工证的学员最真实的声音。我也经历过,那年报名低压电工证,光是操作部分就让我紧张得手心冒汗。很多人觉得考试就是走个形式,但真要动手操作的时候,才发现不是那么回… · 2026/11/12 4:49:07

名山电工证在哪里报名多久拿证 一个济源市政工人的真实经历
名山电工证在哪里报名多久拿证 一个济源市政工人的真实经历

名山电工证在哪里报名多久拿证 一个济源市政工人的真实经历 我是个在济源市从事市政工程的电工,干了八年,最近听说名山那边有个新项目要启动,需要一批持证上岗的电工。我本来以为这事儿简单,结果一打听, 名山电工证在哪里报名… · 2026/11/12 4:49:07

有四级电工证吗?保姆级教程教你快速拿证上岗
有四级电工证吗?保姆级教程教你快速拿证上岗

有四级电工证吗?保姆级教程教你快速拿证上岗 你是不是正被“没有特种作业证就找不到工作”这句话逼得焦头烂额?是不是已经跑遍了当地的培训机构、打听遍了熟人,结果发现 有四级电工证吗… · 2026/11/12 4:49:07

电工证可以操作高压吗?值不值得考?工地太忙根本没时间复习考试
电工证可以操作高压吗?值不值得考?工地太忙根本没时间复习考试

电工证可以操作高压吗?值不值得考?工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是很多一线电工朋友的真实写照。但别以为考个电工证就是走个形式,尤其是现在高压电工证和低压电工证的区分越来越明确, 电工证可以操作高压吗… · 2026/11/12 4:48:07

电工证丢失还能补吗?千万别踩坑,丢了证等于失业
电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/11 12:18:07

电力电缆作业证直播报名入口与办理流程良心建议
电力电缆作业证直播报名入口与办理流程良心建议

电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/11 19:07:25

英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑

英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/11 17:14:54

电工证设年审有效期多久官方回应来了,工地太忙根本没时间复习考试
电工证设年审有效期多久官方回应来了,工地太忙根本没时间复习考试

电工证设年审有效期多久官方回应来了,工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是很多一线电工、焊工、高处作业人员的真实写照。尤其是像你这样刚毕业的鹤壁工程类毕业生,一边要找工作,一边要考证,时间紧张,复习效率低。但你可能不知… · 2026/11/12 0:00:56

新乡电工证实操怕挂科?电工作业动漫图+报考避坑全解析
新乡电工证实操怕挂科?电工作业动漫图+报考避坑全解析

新乡电工证实操怕挂科?电工作业动漫图+报考避坑全解析 实操考试心里没底怕挂科?你不是一个人。新乡的水利工程从业者,很多在报考电工证的时候都担心自己操作不熟练、考试不通过, 千万别踩坑 ,选对资料和方法真的能提高通过率。… · 2026/11/12 0:00:56

网电工证千万别踩坑:实操考试心里没底怕挂科怎么破?
网电工证千万别踩坑:实操考试心里没底怕挂科怎么破?

网电工证千万别踩坑:实操考试心里没底怕挂科怎么破? 实操考试心里没底怕挂科,这是很多准备报考【网电工证】的学员最真实的感受。尤其是在高压电工、低压电工等工种上,操作环节的容错率极低,一旦失误就可能直接被判定不合格。很多人因为担心挂科而放弃考… · 2026/11/12 0:00:56

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/12 4:35:34

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/12 4:36:01

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/11 17:15:20

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码