圆圈最后剩下的数字
0到n-1排列(长度n),每次向后删除第m个数
模拟过程效率不高,鄙人参考官方解答
方法一:数学+递归
- 假设函数f(n,m)返回值为
最终留下的元素的序号
- 第一个删除的元素序号m%n,将前部分的元素接到后面一次类推
- 递归为f(n-1,m)知道剩下的n-1个元素
- 假设答案x=f(n-1,m)
- 长度n的序列最后一个删除的元素为从m%n开始数的第x个数
- f(n,m)=(m%n+x)%n=(m+x)%n
int lastRemaining(int n,int m)
{
if(n==1)
{
return 0;
}
int x=lastRemaining(n-1,m);//假设x为答案,从m%n开始数的第x个元素
return (m+x)%n;
}
//时间与空间均为o(n);
方法二:数学+迭代
修改上面的递归为迭代
int lastNumber(int n,int m)
{
int r=0;
for(int i=2;i!=n+1;++i)
{
r=(m+r)%i;//从最后两个人向最初的n个人推导
}
return r;
}
//时间o(n),空间o(1);
对数学迭代的膜拜!
饮水思源,力扣