左程云_算法与数据结构 — 链表问题 — 06环形单链表的约瑟夫问题_normal&advanced

博客探讨了约瑟夫问题在环形单链表中的实现,提供了两种解决方案:普通方法和高级方法。高级方法利用递推公式和动态规划思想,以O(n)的时间复杂度求解最后存活的节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。[1]
17世纪的法国数学家加斯帕在《数目的游戏问题》中讲了这样一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。、

输入一个环形但想链表的头节点和报数的值m,求最后一个生存下来的节点并且将他形成一个环形单向链表。


思路分析

Nomal

时间复杂度 O(m*n) 空间复杂度O(1)
1. 对链表进行合理性的判断
2. 遍历每一个节点,当报数到了m则删除当前节点
3. 不停的删除直到剩下最后一个节点即为所求

Advanced

时间复杂度O(n)空间复杂度O(1)
需要理解到:最后生存下来的这个节点 => 最后一次删除的节点
所以(感觉像在利用动态规划的思想),假如知道每一次都要删除哪一个节点就可以知道最后一次我要删除哪一个节点,又根据问题可以得知,每一次删除的节点的位置是和上一次删除的节点的位置有一定关系的,所以可以根据每次删除节点的位置关系求出递推公式,然后进行递归求出最后一次删除的节点的位置;
1. 首先我们假设
在总计1个数字的组中最后删除的数字为组中编号1的节点
设为num(1),可以得出num(1)=1;
在总计2个数字的组中最后删除的数字为组中编号num(2)的节点;
在总计3个数字的组中最后删除的数字为组中编号num(3)的节点;
···············以此类推可以得到···············
在总计i-1个数字的组中最后删除的数字为组中编号num(i-1)的节点;
在总计i个数字的组中最后删除的数字为组中编号num(i)的节点;
···
在总计n个数字的组中最后删除的数字为组中编号num(n)的节点;

那么如果可以求出num(i-1)和num(i)的关系就可以得到num(n)的值即为要求的最后剩下节点的值。
2. 在有i个节点的情况下,假如我要报数字 A,求报这个数字的节点编号B:(有多种表示方式)这里使用这个式子(可以验证一下是否符合规律):B = ( A - 1 ) % i +1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值