📜  在第i步中找到捐赠i糖果游戏的赢家(1)

📅  最后修改于: 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,则说明该小朋友没有得到糖果,我们将他从队列的头部移到尾部继续报数。

  • 最后返回队列中唯一的元素即可。