基本问题描述:
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。(也类似于变态杀人狂问题)通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。通常,我们会要求输出最后一位出列的人的序号。那么这里主要研究的是最后一个出列的人的序号要怎么确定。

当n,m数据量很小的时候,我们可以用循环链表模拟约瑟夫环的过程。当模拟到人数等于1的时候,输出剩下的人的序号即可。
具体解法这种方法往往实现起来比较简单,而且也很容易理解。但是时间复杂度却是很糟糕的,达到了O(nm),这样的话,其实在n,m比较大的时候(nm达到10^8或者更大),那么要得出结果往往需要耗费很长的时间,但是我们可以运用一点数学上的技巧,将最后结果推导出来。

为了简化出列的过程:
首先我们把这n个人的序号编号从0~n-1(理由很简单,由于m是可能大于n的,而当m大于等于n时,那么第一个出列的人编号是m%n,而m%n是可能等于0的,这样编号的话能够简化后续出列的过程),当数到m-1的那个人出列,因此我们编号完成之后,开始分析出列的过程:
第一次出列:
一开始的时候,所有人的编号排成序列的模式即为:
0,1,2,3,4,5...n-2,n-1
那么第一次出列的人的编号则是(m-1)%n1,那么在第一个人出列之后,从他的下一个人又开始从0开始报数,为了方便我们设k1 = m%n1(n1为当前序列的总人数)那么在第一个人出列之后,k1则是下一次新的编号序列的首位元素,那么我们得到的新的编号序列为:
k1,k1+1,k1+2,k1+3...n-2,n-1,0,1,2...k1-3,k1-2 (k1-1第一次已出列)
那么在这个新的序列中,第一个人依旧是从0开始报数,那么在这个新的序列中,每个人报的相应数字为:
0,1,2,3....n-2
那么第二次每个人报的相应数字与第一次时自己相应的编号对应起来的关系则为:
0 --> k1
1 --> k1+1
2 --> k1+2
...
n-2 ---> (k1+n-2)%n1(n1为当前序列的总人数,因为是循环的序列,k1+n-1可能大于总人数)
那么这时我们要解决的问题就是n-1个人的报数问题(即n-1阶约瑟夫环的问题)
可能以上过程你还是觉得不太清晰,那么我们重复以上过程,继续推导剩余的n-1个人的约瑟夫环的问题:
那么在这剩下的n-1个人中,我们也可以为了方便,将这n-1个人编号为:
0,1,2,3,4...n-2
那么此时出列的人的编号则是(m-1) % n2(n2为当前序列的总人数),同样的我们设k2 = m % n2,那么在这个人出列了以后,序列重排,重排后新的编号序列为:
k2,k2+1,k2+2,k2+3...n-2,n-1,0,1,2...k2-3,k2-2 (k2-1第一次已出列)
那么在这个新的序列中,第一个人依旧是从1开始报数,那么在这个新的序列中,每个人报的相应数字为:
1,2,3,4....n-2
那么这样的话是不是又把问题转化成了n-2阶约瑟夫环的问题呢?
后面的过程与前两次的过程一模一样,那么递归处理下去,直到最后只剩下一个人的时候,便可以直接得出结果
当我们得到一个人的时候(即一阶约瑟夫环问题)的结果,那么我们是否能通过一阶约瑟夫环问题的结果,推导出二阶约瑟夫环的结果呢?
借助上面的分析过程,我们知道,当在解决n阶约瑟夫环问题时,序号为k1的人出列后,剩下的n-1个人又重新组成了一个n-1阶的约瑟夫环,那么
假如得到了这个n-1阶约瑟夫环问题的结果为ans(即最后一个出列的人编号为ans),那么我们通过上述分析过程,可以知道,n阶约瑟夫环的结果
(ans + k)%n(n为当前序列的总人数),而k = m%n
则有:
n阶约瑟夫环的结果

(ans + m % n)%n,那么我们还可以将该式进行一下简单的化简:

当m<n时,易得上式可化简为:(ans + m)% n

而当m>=n时,那么上式则化简为:(ans % n + m%n%n)% n
即为:(ans % n + m%n)% n
而 (ans + m)% n = (ans % n + m%n)% n
因此得证
(ans + m % n)%n = (ans + m)% n
这样的话,我们就得到了递推公式,由于编号是从0开始的,那么我们可以令
f[1] = 0; //当一个人的时候,出队人员编号为0
f[n] = (f[n-1] + m)%n //m表示每次数到该数的人出列,n表示当前序列的总人数
而我们只需要得到第n次出列的结果即可,那么不需要另外声明数组保存数据,只需要直接一个for循环求得n阶约瑟夫环问题的结果即可
由于往往现实生活中编号是从1-n,那么我们把最后的结果加1即可。

代码:

# -*- coding:utf-8 -*-
class Solution:def LastRemaining_Solution(self, n, m):if n < 1:return -1con = range(n)final = -1start = 0while con:k = (start + m - 1) % nfinal = con.pop(k)n -= 1start = kreturn final

约瑟夫环问题 - Python相关推荐

  1. 【循环链表】约瑟夫环问题——Python

    背景:故事源自著名犹太历史学家Josephus,在罗马人占领乔塔帕特后,39个犹太人与Josephus以及他的朋友躲进了一个山洞中,39个犹太人决定宁死不屈,于是决定了一个自杀方式,41个人排成一个圈 ...

  2. 约瑟夫环问题python解法_约瑟夫环问题python解法 | 学步园

    约瑟夫环问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到k的那个人被杀掉:他的下一个人又从1开始报数,数到k的那个人又被杀掉:依此规律重复下去,直到 ...

  3. 约瑟夫环问题python解法_约瑟夫环问题python解法

    约瑟夫环问题:已知n个人(以编号1,2,3-n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到k的那个人被杀掉:他的下一个人又从1开始报数,数到k的那个人又被杀掉:依此规律重复下去,直到圆桌 ...

  4. 算法-约瑟夫环问题——python实现

    Hello NanFeng 遇到了一个有点意思的题: 一艘船上有30个人,现在因为超载需要15人下船,决策者采用了一种很特殊的抽签方式 1.先让人们排成一列,按照顺序给每个人编号 2.依次从1开始报数 ...

  5. 约瑟夫环问题-python代码

    问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人 ...

  6. 约瑟夫环问题——python

    https://blog.csdn.net/qq_43497702/article/details/88047489

  7. python中约瑟夫环程序_Python实现约瑟夫环问题的方法

    本文实例讲述了Python实现约瑟夫环问题的方法.分享给大家供大家参考,具体如下: 题目:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的 ...

  8. python约瑟夫环问题给十个学生编号报到3者出列_趣味算法--约瑟夫环问题(示例代码)...

    问题描述 已知n个人(以编号1,2,3,...,n分别表示)围坐在一张圆桌上.指定编号为k的人开始从1报数,数到m的那个人出列:出列那个人的下一位又从1开始报数,数到m的那个人出列:以此规则重复下去, ...

  9. python解决约瑟夫问题_Python实现约瑟夫环问题的方法

    本文实例讲述了Python实现约瑟夫环问题的方法.分享给大家供大家参考,具体如下: 题目:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的 ...

最新文章

  1. 视频动作识别--Towards Good Practices for Very Deep Two-Stream ConvNets
  2. 吴恩达机器学习笔记——第一章
  3. Elasticsearch的PHP的API使用(一)
  4. 网狐棋牌(二) CQueueServiceEvent初步分析
  5. 主要的css hack
  6. 家装强电弱电布线图_家装电路改造注意事项是什么?深圳广田家透彻分析全搞定...
  7. linux shell 流程控制(条件if,循环【for,while】,选择【case】语句实例
  8. 2013.8.4thinkPHp学习
  9. Python学习笔记--CSV模块读写数据(转)
  10. 用luac给lua脚本加密
  11. python psutil 汇总 tcy
  12. 金仓数据库在 TPCE(dbt5,tpsE)测试框架方面的实践和突破
  13. 微服务项目:尚融宝(40)(核心业务流程:申请借款额度(3))
  14. Flutter UI自动化测试技术方案选型与探索,初面蚂蚁金服
  15. OpenStack社区周报:Neutron网络之负载均衡,设计OpenStack云时需要避开的十个误区...
  16. win7环境下 net start npf服务名无效的解决方法。
  17. 工作了这么长时间,是不是非用macbook pro不可呢?
  18. MediaPlayer提示“无法播放视频”
  19. 设置U8g2库函数字体的方法
  20. python基础-数据类型转换

热门文章

  1. linux内核崩溃+grub,Linux内核崩溃信息分析
  2. C语言数组讲解(1)一维数组的创建和初始化。
  3. Android保存搜索历史
  4. In file included from scripts/kconfig/lxdialog/checklist.c:24:0: scripts/kconfig/lxdialog/dialog.h:3
  5. (转)数据挖掘岗求职经验:腾讯+百度+华为(均拿到sp offer)
  6. DeDeCMS v5.7 SP2 前台任意用户密码修改漏洞复现
  7. “贵人语迟”?孩子说话越晚越聪明?
  8. 营收130亿净利却只有8亿,统一的钱都花在了哪?
  9. SQL Server 方言类型映射问题
  10. kotlin 使用ButterKnife