问题:
0,1,2,...n这n个数排成一个圈, 从数字0开始,每次从这个圈里删除第m个数字.删除后从下一个数字开始,求出从这个圈里剩下的最后一个数字.
例如:0,1,2,3,4,5 m=3 最后剩下的是数字3.
分析:
首先,我们考虑是否能够按照平时最常规的方法(循环处理的方式进行求解)进行处理.虽然能够处理但时间复杂度应该比较高.但我们在这里也把代码写出来.大家可以参考一下.
典型的减少时间复杂度的算法就是动态规划法(以空间换取时间).动态规划法的关键一步就是需要找到状态转移方程.具体实现如算法2.
算法:
算法1,使用循环处理的方式,但这种方法时间复杂度较高.这种方法在leetcode上测试,如果输入规模较大,就会显示执行超时!
class solution{
public:
int lastRemaining(int n, int m){
vector<int> nums;
int idx;
for(int i = 0; i < n; i++){
nums.push_back(n);
}
while(n > 1){
idx = (idx+m)%n;
nums.erase(nums.begin()+idx);
n--;
}
return nums[0];
}
};
算法2,
class solution{
public:
int lastRemaining(int n, int m){
return f(m, n);
}
int f(int n, int m){
int x;
if (n == 1)
return 1;
x = f(n-1,m);
return (m%n+x)%n;
}
};