leetcode 圆圈中最后剩下的数字(思路)

leetcode 面试题62. 圆圈中最后剩下的数字

2020/3/30 感觉这个题的思路很重要,保存以备今后参考!

题目:0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
例如:0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

示例:

输入: n = 5, m = 3
输出: 3
输入: n = 10, m = 17
输出: 2

解题思路:
阅前提示(全文最重要的点):
只关心最终活着那个人的序号变化
1 约瑟夫问题
这个问题实际上是约瑟夫问题,这个问题描述是:
N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报。如此反复,最后剩下一个,求最后的胜利者。

2 问题转换
既然约塞夫问题就是用人来举例的,那我们也给每个人一个编号(索引值),每个人用字母代替
下面这个例子是N=8 m=3的例子:
我们定义F(n,m)表示最后剩下那个人的索引号,因此我们只关心最后剩下来这个人的索引号的变化情况即可
在这里插入图片描述
从8个人开始,每次杀掉一个人,去掉被杀的人,然后把杀掉那个人之后的第一个人作为开头重新编号
3 最终活着的人编号的反推
如何才能将N = 7 的排列变回到N = 8 呢?
我们先把被杀掉的C补充回来,然后右移m个人,发现溢出了,再把溢出的补充在最前面

在这里插入图片描述
推出递推公式: f(8,3)=[f(7,3)+3]%8
进行推广泛化 f(n,m)=[f(n−1,m)+m]%n

python程序:

def f(n, m):
    if n == 0:
        return 0
    return (f(n-1,m) + m) % n
class Solution(object):
    def lastRemaining(self, n, m):
       return f(n,m)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值