圆圈中最后剩下的数字 —— 约瑟夫环问题

问题

模拟求解流程

设 n = 5, m = 3

n = 5, 0, 1, 2, 3, 4 => 0, 1, 2, 3, 4
n = 4, 3, 4, 0, 1     => 3, 4, 0, 1
n = 3, 1, 3, 4         => 1, 3, 4
n = 2, 1, 3             => 1, 3
n = 1, 3                 => END

由于每趟从被删除元素之后开始数,我把被删除的元素都移到数组中的第一个位序。

那么,可以观察到被删除的总是下标为(0 + m) mod n的元素;
删除元素后,其他的元素都向前移动了m位,最终坐落在坐标为(idx - m) mod (n -1)的位置上(idx为元素未移动前的坐标)

依照上面的话, 我们只需要知道某个数的坐标就能反推出该数在上一趟的坐标。

自下而上推导

由上述的求解流程,我们可以肯定的是最后一趟(即n=1时), 只有一个数,而且其坐标一定为0

假设idx1的意思是解在剩余n人时的坐标位置。

已知 idx1 = 0

由于相比上一趟所有元素都移动了3位,那么应该往后挪3位才能推到原来的位置上。

因此,
idx2 = (idx1 + 3) mod 2 = (0 + 3) mod 2 = 1
idx3 = (idx2 + 3) mod 3 = (1 + 3) mod 3 = 1
idx4 = (idx3 + 3) mod 4 = (1 + 3) mod 4 = 0
idx5 = (idx4 + 3) mod 5 = (0 + 3) mod 5 = 3

答案呼之欲出 😃
因此,只有5个元素时,最后剩下的一定是坐标为3的元素。


推导出一般方程
i d x n = ( i d x n − 1 + m )   m o d   n    ( n ≥ 1 ) idx_n = (idx_{n-1} + m) \space mod \space n \space\space (n \ge 1) idxn=(idxn1+m) mod n  (n1)


代码实现

def GetFinalIndex(n: int, m: int) -> int:
    idx = 0
    k   = 2
    while k != n + 1:
        idx = (idx + m) % k
        k += 1
    return idx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值