题目
0, 1, …, n-1这n个数字(n>0)排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。
求出这个圆圈里剩下的最后一个数字。
样例
输入:n=5 , m=3
输出:3
解法一:模拟
c++中list容器用作双向链表
时间复杂度O(nm),空间复杂度O(n)
#include <list>
class Solution {
public:
int lastRemaining(int n, int m){
list<int> l;
for (int i = 0; i < n; i++)
l.push_back(i);
int cnt = m - 1;
auto it = l.begin();
while (l.size() > 1) {
while (cnt--) {
it++;
if (it == l.end()) it = l.begin();
}
it = l.erase(it);
if (it == l.end()) it = l.begin();
cnt = m - 1;
}
return l.front();
}
};
解法二:DP
dp(n, m) 表示n个人, m为号的最后结果
每次删除一个人后重新编号
那么 dp(n, m) = (dp(n - 1, m) + m) % n
因为此时0的位置是原来m的位置
时间复杂度O(n),空间复杂度O(1)
class Solution {
public:
int lastRemaining(int n, int m){
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += m;
if (ans >= i) ans %= i;
}
return ans;
}
};
// class Solution {
// public:
// int lastRemaining(int n, int m){
// if (n == 0) return 0;
// return (lastRemaining(n - 1, m) + m) % n;
// }
// };