面试题62. 圆圈中最后剩下的数字

一共 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/


sxwxs
292 声望21 粉丝

计算机专业学生