约瑟夫(joseph)问题
约瑟夫是一个经典的问题,提供了一种简单的递推思路。
基础知识
约瑟夫问题,又被叫做“约瑟夫斯变换”,是一个很经典的动态规划方面的问题。问题的描 述是这样的。有n个人,从1开始编号至n,这n个人排成一个圆圈,从第一个人开始报数,报到m的人出列,剩下的人重新围成圆圈,从出列的那个人的下一个人开始又从1开始报数,以此类推。直到圆圈里最后剩下一个人为止,现在求这个人的编号。
问题解法
关于约瑟夫问题,主要有以下几种形式:
朴素解法(模拟)
根据问题描述,模拟出圈动作的进行。建议写成循环链表的形式。
这种方法可以解出每次出圈的人在 整个圈 的编号,时间复杂度有点高。
代码示例(数组模拟):
求解最后出圈的人
为了讨论方便,先把问题稍微改变一下,并不影响原意:
问题描述:n个人(编号0~(n-1) ),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。
我们知道第一个人(编号一定是(m-1) mod n) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m mod n的人开始):
k k+1 k+2 ... n-2,n-1,0,1,2,... k-2
并且从k开始报0。
现在我们把他们的编号做一下转换: