圓圈最後剩下的數字
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);
對數學迭代的膜拜!
飲水思源,力扣