LeeCode 1832 找出游戏的获胜者
LeeCode 1832
题目描述:
共有 n 名小伙伴一起做游戏。小伙伴围成一圈,按顺时针顺序从1到n编号。确切地说,从第 i 名小伙伴顺时针移动一位会到达第 (i+1) 名小伙伴的位置,其中 1 <= i < n,从第 n 名小伙伴顺时针移动一位会回到第 1 名小伙伴的位置。
游戏遵顼如下规则:
- 从第 1 名小伙伴所在位置开始
- 沿着顺时针方向数 k 名小伙伴,计数时需要包含起始时位置的那位小伙伴。逐个绕圈进行计数,一些小伙伴可能会被数过不止一次
- 你数到的最后一名小伙伴需要离开圈子,并视作输掉游戏
- 如果圈子中仍然有不止一名小伙伴,从刚刚输掉的小伙伴的顺时针下一位小伙伴开始,回到步骤2继续执行
- 否则,圈子中最后一名小伙伴赢得游戏
给你参与游戏的小伙伴总数 n,和一个整数k,返回游戏的获胜者
标签: 动态规划、约瑟夫环
建立模型
- 假设当前有 n 个人,位置为 k 的小伙伴退出游戏
- 观察下标变化
# 1 -> n-k+1
# 2 -> n-k+2
# ...
# k -> 退出游戏
# k+1 -> 1
# k+2 -> 2
# ...
# n -> n-k
由上面的规律可以得到这样一个关系式:
\[f(n) = (f(n - 1) + k - 1) \% n + 1
\]
编码实现
def findTheWinner(n: int, k: int) -> int:
# 初始状态, n=1时获胜者就是该小伙伴
winner = 1
for i in range(2, n+1):
winner = (winner + k - 1) % n + 1 # 状态转移方程
return winner