1、题目描述
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
示例 1:
输入: n = 5, m = 3
输出: 3
示例 2:
输入: n = 10, m = 17
输出: 2
2、VS2019上运行
使用递归的方法
#include <iostream>class Solution {// 递归函数,计算在长度为n的序列中每次删除第m个数字后剩下的数字的索引int f(int n, int m) {if (n == 1) return 0; // 边界条件:序列长度为1,剩下的数字的索引为0return (f(n - 1, m) + m) % n; // 使用递归和数学公式计算剩下的数字的索引}
public:// 主函数,调用递归函数求解最终结果int lastRemaining(int n, int m) {return f(n, m);}
};int main() {Solution solution;int n = 5;int m = 3;int result = solution.lastRemaining(n, m);std::cout << "The last remaining number is: " << result << std::endl;return 0;
}
The last remaining number is: 3
3、解题思路
黄彬彬
- 1.如果序列长度为1(即n=1),那么剩下的数字的索引就是0,直接返回 0。
- 2.如果序列长度大于1,我们可以利用递归调用 f(n-1, m) 来求解长度为n-1的序列中每次删除第m个数字后剩下的数字的索引。
- 3.根据约瑟夫环问题的特性,我们可以通过公式 (f(n-1, m) + m) % n 来计算在长度为n的序列中每次删除第m个数字后剩下的数字的索引。这个公式结合了递归调用的结果和挪动m位的操作。