剑指 Offer 62. 圆圈中最后剩下的数字

剑指 Offer 62. 圆圈中最后剩下的数字

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

示例 1:


输入: n = 5, m = 3

输出: 3

示例 2:


输入: n = 10, m = 17

输出: 2

限制:

  • 1 <= n <= 10^5

  • 1 <= m <= 10^6

来源:力扣(LeetCode)

链接:力扣

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一解

  • 旧编号从第一位开始数

  • 新编号,删除 m 后,从 m+1 开始数

两者编号关系为:

  • 0, 1,2,…,m, m+1…

  • -m, 1-m, 2-m,…,m,0…

旧编号 = 新编号 + m

可通过递归层层求解旧编号:


class Solution:

    def lastRemaining(self, n: int, m: int) -> int:

        if n == 1: return 0

        # 旧编号 = (新编号 + m)n

        return (self.lastRemaining(n - 1, m) + m) % n

二解

与一解思路类似,使用动态规划替换递归:


class Solution:

    def lastRemaining(self, n: int, m: int) -> int:

        res = 0

        for i in range(2, n+1):

            res = (res + m) % i

        return res