📅  最后修改于: 2023-12-03 15:23:35.803000             🧑  作者: Mango
有 $n$ 个小朋友在玩捐赠糖果游戏,编号为 0 到 n-1。 他们按顺时针方向围成一个圈。每个小朋友都有一个数字值 $c_i$,表示他捐赠给此次游戏的糖果数量。
游戏按顺时针顺序进行,每个小朋友轮流报数,报到糖果数时获得圈子中的捐赠糖果,然后下一个小朋友继续报数。如果某个小朋友在报数时得到的糖果数超过了剩余的糖果数,则他只得到剩余的糖果数,并退出游戏。当这个小朋友退出游戏时,下一个小朋友开始从 1 再次报数。
最后剩余的糖果数量将会给编号为最后获得糖果的小朋友当作奖励。
请写一个函数,来帮助你找到最后获得糖果的小朋友的编号。
这个问题可以用环形链表来解决。我们可以使用 deque
来代替手写的环形链表。每次从开头 popleft()
一个值,计算剩余糖果,如果还有糖果,则加入尾部 append()
继续报数。
当队列中只剩下一个小朋友时,他就是最后获得糖果的小朋友。我们记录每次从队列中弹出的编号,最后即可得出答案。
from collections import deque
def findTheWinner(n: int, k: int) -> int:
q = deque(range(1, n+1))
cnt = 0
while len(q) > 1:
cnt += 1
if cnt == k:
q.popleft()
cnt = 0
else:
q.append(q.popleft())
return q[0]
n = 5
k = 2
print(findTheWinner(n, k)) # 输出 3
代码解释:
首先将小朋友的编号从 1 到 n 入队,形成队列 q
。
然后开始对队列进行操作,不断从队列中弹出值,直到队列中只剩下一个元素,则该元素即为最后获得糖果的小朋友。
在每次操作中,我们用变量 cnt
记录当前报数的个数。如果 cnt
等于 k,则说明当前小朋友将得到糖果,他将被弹出队列。
如果 cnt
不等于 k,则说明该小朋友没有得到糖果,我们将他从队列的头部移到尾部继续报数。
最后返回队列中唯一的元素即可。