约瑟夫环问题是一个经典的数学和计算机科学问题。在约瑟夫环问题中,有n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。例如,当数字是0、1、2、3、4,并且每次删除第3个数字时,删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
Python
class Node:
def __init__(self,val=0,next=None):
self.val = val
self.next = next
def createHuan(n):
'''构建环形链表'''
dummy = Node() # 游离节点
first = Node() # 头节点
# 环构建的时候分为三种情况
for i in range(1,n+1):
# 1.头节点:直接创建,无指向
if i == 1:
first = Node(val=i)
dummy = first
continue
# 2.中间节点:创建新节点(val为编号)同时让前驱节点指向新节点,最后在赋值为新节点
node = Node(val=i)
dummy.next = node
dummy = node
# 3.尾节点:需拿尾节点再指向头节点,构成环
if i == n:
dummy.next = first
return first # 返回头节点
def main():
n,m = map(int,input().split()) # 输入n,m
first = createHuan(n) # 得到环的头节点
count = 0 # 计数器,每逢m更新为0
pre = Node() # 前驱节点,方便删除数到m的节点
while first.next != first: # 当最后只剩下一个节点的时候,他的指针也指向他自己,则退出循环
count += 1 # 每轮循环计数器加1
if count == m:
print(first.val,end=',') # 打印该节点编号
pre.next = first.next # 删除该节点
pre = first
first = first.next
count = 0
else: # 俩个节点同时往后走
pre = first
first = first.next
print(first.val) # 打印最后一个节点的编号
if __name__ == '__main__':
main()