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
1、题目分析
把0~n-1的数字围成一个圈圈,然后从0开始删除第m个数字,然后再从m之后的那个数字开始新一轮的删除游戏,直到这个圈了剩下最后一个元素,返回这个元素即可。所以关键点就来了,如果找到删除之后的那个位置;如果m的长度是大于n怎么办?;
对于第一个关键点:要删除的位置是(i+m-1)
对于第二个关键点:如果大于n就取模(i+m-1)%n
找到删除的下标就弹出元素即可,弹出之后列表往前移动一个单位,所以下一次的起始位置就是i = (i+m-1)%n.这个非常重要。
2、解题分析
- 初始化一个0~n-1之间的列表res,和下标i=0
- 如果res的长度是大于1
- 待删除的坐标i = (i+m-1)%len(res);len(res)非常重要,因为每次删除都更新这个值
- 然后从数组中弹出该值
- 否则返回res[0]
3、代码
class Solution:
def lastRemaining(self, n: int, m: int) -> int:
res = [i for i in range(n)]
i=0
while len(res)>1:
i = (i+m-1)%len(res)
res.pop(i)
return res[0]
图示:
总结:待删除的坐标和下一次初始的坐标是一样的,这个非常巧妙。