题目
-
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
-
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
-
leetcode链接:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/
思路
- 数学归纳法
// m = 3, n = 2
// 首先最后一轮中num的下标一定是0, 这个是已知的。
// 那上一轮应该是有两个元素,此轮次中 num 的下标为 (0 + m)%n = (0+3)%2 = 1; 说明这一轮删除之前num的下标为1;
// 再上一轮应该有3个元素,此轮次中 num 的下标为 (1+3)%3 = 1;说明这一轮某元素被删除之前num的下标为1;
// 再上一轮应该有4个元素,此轮次中 num 的下标为 (1+3)%4 = 0;说明这一轮某元素被删除之前num的下标为0;
// 再上一轮应该有5个元素,此轮次中 num 的下标为 (0+3)%5 = 3;说明这一轮某元素被删除之前num的下标为3;
// ....
// 因为我们要删除的序列为0-n-1, 所以求得下标其实就是求得了最终的结果。比如当n 为5的时候,num的初始下标为3,
// 所以num就是3,也就是说从0-n-1的序列中, 经过n-1轮的淘汰,3这个元素最终存活下来了,也是最终的结果。
// 总结一下推导公式:(此轮过后的num下标 + m) % 上轮元素个数 = 上轮num的下标
/**
* @param {number} n
* @param {number} m
* @return {number}
*/
var lastRemaining = function (n, m) {
let ans = 0 // 最后一轮下标肯定为0
// 往前推,最后一轮是1个人,那么再往前是两个人
for (let i = 2; i <= n ; i++) {
ans = (ans + m) % i
}
return ans
}