问题:
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;
}
};
这篇博客探讨了一种数学问题,即在0到n的序列中,每次删除第m个数字,如何找出最后剩下的数字。博主首先介绍了常规的循环处理方法,虽然能解决问题但效率较低,容易导致超时。接着,博主提出了一种优化算法,使用动态规划法降低时间复杂度。通过递归实现的状态转移方程,实现了高效求解此问题的算法。

被折叠的 条评论
为什么被折叠?



