题目描述
0, 1, …, n-1这n个数字(n>0)排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。
求出这个圆圈里剩下的最后一个数字。
样例
输入:n=5 , m=3
输出:3
问题分析
在这n个数字中,第一个被删除的数字是(m-1)%n,为简单起见记为k。那么删除k之后的剩下n-1的数字为0,1,…,k-1,k+1,…,n-1,并且下一个开始计数的数字是k+1。相当于在剩下的序列中,k+1排到最前面,从而形成序列k+1,…,n-1,0,…k-1。接下来我们把剩下的的这n-1个数字的序列k+1,…,n-1,0,…k-1作一个映射,映射的结果是形成一个从0到n-2的序列:
k+1 -> 0
k+2 -> 1
…
n-1 -> n-k-2
0 -> n-k-1
…
k-1 -> n-2
可以发现,如果映射之后的数字是x,那么x对应的映射前的数字为(x+k+1)%n。记最初的序列最后剩下的数字为f(n,m),由于映射之后的序列和最初的序列有同样的形式,都是从0开始的连续序列,因此仍然可以用函数f来表示,那么映射后的序列最后剩下的数字为f(n-1,m),然后我们需要把它映射到最初的序列的标号,所以为:( f(n-1,m) + k + 1) % n,化简后得:[f(n-1,m)+m]%n。于是便可以写出代码了。
代码实现
class Solution {
public:
int lastRemaining(int n, int m){
if(n == 1)
return 0;
return (lastRemaining(n-1, m) + m) % n;
}
};