法1:约瑟夫环递归
n个数相后去掉第m个数,还剩下n−1个数,依然要继续去掉第m个数。由此,从(n,m)的问题变成了(n−1,m)的子问题。时间复杂度和空间复杂度都是On
说实话不理解,先背住吧
int f(int n,int m){
if(n == 1)
return 0;
else
return (f(n-1,m) + m) % n;
}
int LastRemaining_Solution(int n, int m) {
if(n<1|| m<1)
return -1;
return f(n,m);
}
法2:暴力模拟
int LastRemaining_Solution(int n, int m) {
if(n == 1) return 0;
vector<int> child;
child.resize(n, 0); // 标记是否在圈内 0在 1已出圈
int cnt = 0; // cnt用以记录出圈的小孩个数
int j = 0; // j为当前的报数
for(int i = 0; cnt != n-1; i = (++i) % n){
if(child[i] == 0){
j++; //在圈内 报数
if(j == m){
j = 0;
child[i] = 1;
cnt++;
}
}
}
for (int i = 0; i < n; i++) { // 找到唯一剩下的孩子
if (!child[i]) return i;
}
return -1;
}