一共 n 个元素,围成一圈,从第 0 个开始,每数 m 个删除一个。求最后剩下的是哪个。
首先把 n 个元素看成从 0 到 n - 1 的序列。
如果只有一个元素,剩下的一定是 0 号。
可以把 n 个元素每 m 个删除一个的问题定义为 f(n, m),可以通过 f(n-1, m) 的解得到 f(n, m) 的解。这里 m 是固定的,可以省略,就是 f(n) 了。
f(1) = 0
看如何从 f(n-1) 得到 f(n):
f(n) 删除了第 m 个,还剩 n - 1 个,是 0 到 m - 1 和 m + 1 到 n - 1,且对于 f(n-1) 来说,起点是 m+1。如果已经得到 f(n-1),设为 x,但 f(n-1) 的编号的起点和 f(n) 不同。需要把 f(n-1) 的编号转换为 f(n) ,就是 f(n) = (m + f(n-1)) % n。
递归
因为 python 有最大递归层数限制,需要通过 sys.setrecursionlimit(100000) 把限制提高。
sys.setrecursionlimit(100000)
class Solution:
def lastRemaining(self, n: int, m: int) -> int:
def f(n):
if n == 1:
return 0
if n == 2:
return m % 2
return (f(n-1) + m) % n
return f(n)
递推
class Solution:
def lastRemaining(self, n: int, m: int) -> int:
x = 0
for i in range(1, n+1):
x = (x + m) % i
return x
这里有一道 n 最大是 100 位数字但是 m 为 2 的题目:https://vijos.org/p/1095
欢迎来我的博客: https://codeplot.top/
我的博客刷题分类:https://codeplot.top/categories/%E5%88%B7%E9%A2%98/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。