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

思路1:模拟,用链表或者一个队列即可实现,但时间复杂度过高。

思路2: 数学推理

设 f(n,m)表示长度为n的序列,每次删除第m个以后,最后剩下的数字。

那么,第一个删除的应该是(m-1)%n ,设k=(m-1)%n

那么剩下的序列应该是 k+1 ,k+2 ....n-1, 0 ,1 ,....k-1         序列有n-1个数

接下来应该做的是对上面的序列求F(n-1,m) ,这里之所以用F,而不用f。是因为序列已经发生了变化。

如果我们能将序列转成从 0开始的n-1个数,那么就可以使用 f(n-1,m) 了。

如何做呢?我们来看一下映射关系。

k+1 对应 0

k+2  对应1

k+3 对应 2

......

k-1 对应 n-1

如何实现上述的转换? (x-k-1)%n 即可,其中x表示(k+1,k+2.....)

但其实我们需要的是从0,1,...n-1到k+1,k+2的映射关系

即 (x+k+1)%n,也就是说,我只要在f(n-1,m)中求出剩下的那一个数,通过(x+k+1)%n 就可以转回来,它在原序列中对应的数。

所以可以递归实现。(x+k+1)%n == ((f(n-1,m)+(m-1)%n+1)%n == (f(n-1,m)+m)%n

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值