剑指-面试题62 圆圈中最后剩下的数字

约瑟夫环

题目 约瑟夫环问题
0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

思路

        将问题建模为函数 f ( n , m ) f(n,m) f(n,m),该函数返回值为最终留下的元素的序号。
        首先, 长度为 n n n的序列会先删除第 m % n m\%n m%n个元素,然后剩下一个长度为 n − 1 n-1 n1的序列,于是可以递归求解 f ( n − 1 , m ) f(n-1,m) f(n1,m),得到对于剩下的 n − 1 n-1 n1个元素,最终留下的元素的序号, f ( 1 , m ) f(1, m) f(1,m)即为所求。
        由于删除了第 m % n m\%n m%n个元素,将序列的长度变为 n − 1 n-1 n1。当知道 f ( n − 1 , m ) f(n-1,m) f(n1,m)对应的答案 x x x后,就可以知道,长度为 n n n的序列最后一个删除的元素,应该是从 m % n m\%n m%n开始的第 x x x个元素。因此
f ( n , m ) = ( m % n + x ) % n = ( m + x ) % n f(n,m)=(m\%n+x)\%n=(m+x)\%n f(n,m)=(m%n+x)%n=(m+x)%n
递归:

  • 时间复杂度: O ( n ) O(n) O(n),需要求解的函数值有 n 个。
  • 空间复杂度: O ( n ) O(n) O(n),递归深度为n。

迭代:

  • 时间复杂度: O ( n ) O(n) O(n),需要求解的函数值有 n 个。
  • 空间复杂度: O ( 1 ) O(1) O(1),只使用常数个变量。

C++ 递归

class Solution {
public:
    int lastRemaining(int n, int m) {
        return func(n, m);
    }
private:
    int func(int n, int m)
    {
        if(n==1)
            return 0;
        int x = func(n-1, m);
        return (m+x)%n;
    }
};

python 迭代

class Solution:
    def lastRemaining(self, n: int, m: int) -> int:
        f = 0
        for i in range(2, n+1):
            f = (m+f)%i
        return f
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值