约瑟夫问题
:有 N 个人围成一圈,每个人都有一个编号,编号由入圈的顺序决定,第一个入圈的人编号为 1,最后一个为 N,从第 k (1<=k<=N)个人开始报数,数到 m (1<=m<=N)的人将出圈,然后下一个人继续从 1 开始报数,直至所有人全部出圈,求依次出圈的编号。
基于单向环形链表实现:
-
初始化一个单向环形链表:
-
使用变量
- first:指向第一个元素,起始的first应该为null,当链表添加第一个节点时,first应该指向该节点,且first的next指向自己
- curBoy:指向当前的节点(也是当前链表的最后一个节点),因为first作为第一个节点不能随意改动,所以curBoy作为first的辅助变量
-
实现思路:
循环创建Boy节点,当创建第一个Boy节点时,将first指向它,且first的next指向自己,同时记录当前链表的最后一个节点curBoy;从第二个节点开始,每次添加节点在curBoy后,并将其next指向first,然后记录curBoy
-
-
计算出圈顺序:
-
使用变量
- helper:指向first的前一个节点
- first:表示当前开始数数的起始节点
-
实现思路:
首先要将helper指向first的前一个节点,也就是链表的最后一个节点;接着要将first移动到启动点startNo,helper要随之移到到其前一个节点;然后first和helper循环移动m-1次,移动后的first指向的就是需要出圈的节点,执行first = first.next helper.next = first即可将其出圈,直到链表中只剩下一个节点时,结束游戏。
-