【算法】数据结构与算法分析学习笔记——第三章习题选做Josephus问题

来源:互联网 发布:软件测试覆盖率 编辑:程序博客网 时间:2024/05/21 19:26

3.14Josephus问题可以描述为如下的一个游戏:N个人编号从1到N,围坐成一个圆圈,从1号开始传递一个热土豆,经过M次传递后拿着土豆的人离开圈子,由坐在离开的人的后面的人拿起热土豆继续进行游戏,直到圈子只剩下最后一个人。例如:M=0,N=5,则游戏人依次被清除,5号最后留下;如果M=1,N=5,那么被清除的人的顺序是2,4,1,5,最后剩下的是3号。

这里给出两种实现方法,第一种是最容易想到的,也就是直接程序模拟实现,用数组链表都可以,直接贴代码,是用单循环链表实现的,这种方法的时间复杂度是O(MN)

代码如下:


然后介绍一种递推的方法,我们再回到题目去分析,就使用M=3,N=4的例子吧

我们可以想想,在最后剩下一个人的时候,我们虽然不知道这个人原先的编号,但是我们可以确定他是第0个(也就是说每次出队后都把剩下的重新编号),那么是否可以反推过去,算出他原来的编号呢?

画个图形象一点


每一次出队后,由出队的下一个作为0,很快就可以发现规律,

第一次n=4,3-->0,0(+4)-->1,1(+4)-->2

第二次n=3,0(+3)-->0,1(+3)-->1

第三次n=2,1(+2)-->0

换成通项公式就是f(n-1)=[ f(n) - M ] % n  

如果反过来推就是f(n)=[ f(n-1) + M ] % n

代码如下:


3.22提出支持栈的Push和Pop操作以及第三种操作FindMin的数据结构,其中FindMin返回该数据结构的最小元素 所有操作在最坏的情况下的运行时间都是O(1)

感受一下作者的脑洞。。。


1 0