1.著名的Josephus问题
据说著名犹太 Josephus有过以下的故事:在罗⻢⼈占领乔塔帕特后,39个犹太⼈与 Josephus及他的朋友躲到⼀个洞中,39个犹太⼈决定宁愿死也不要被⼈抓到,于是决定了⼀个⾃杀 ⽅式,41个⼈排成⼀个圆圈,由第1个⼈开始报数,每报数到第3⼈该⼈就必须⾃杀,然后再由下⼀ 个重新报数,直到所有⼈都⾃杀⾝亡为⽌。 历史学家 然⽽Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与⾃⼰安排在 第16个与第31个位置,于是逃过了这场死亡游戏。
2.题目
3.思路分析
(1)创建环形链表
循环链表:节点的next指针不为空!而是指向链表的第一位存储有效数据的节点。
创建快慢指针;pcur(快指针),prev(慢指针) ,初始化时prev指向链表中第一位有效数据所在的节点,pcur指向prev的下一个节点。
(2)计数
设想:从第一个人开始,人所报出的数字就是count,那么我们要对count后续会进行count++和count的初始化操作。
count用来计数,初始化count = 1,因为题目说从编号一开始报数。
(i)在count != m的情况下,pcur和prev指针都要后移一位, 并且count要++,以达到计数的效果。
(ii) 在count == m的情况下, 要销毁pcur所在的节点,prev指针指向pcur的下一个节点,释放掉pcur后,让pcur指针重新指向prev指针所指向节点的下一个节点。此时,count要初始化为1(后续count重新从1开始计数!)。
上述两种情况都在循环里发生 ,最终留下的节点就是最后一个节点pcur(prev),此时pcur与prev同时指向最后一个节点。
循环的终止条件是:pcur的next指针指向自己(因为所创建的链表是循环链表)!