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;
    }
};
发布了449 篇原创文章 · 获赞 197 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/qq_40774175/article/details/105192742