约瑟夫环时间复杂度O(n)解法

  • 约瑟夫环我想大家都了解,这里再简单介绍下,n, m分别代表
    n个人围成圈,编号分别为1~n,从1号开始报数,m号出列,然后重新从1开始报数,到m再出列,直到整个环只剩一个人,输出这个人的编号。

  • 最常规的做法当然就是用链表模拟整个操作过程。这种方法,每一个人出列,都要数m次,时间复杂度会达到O(n*m)。

  • 有一种有趣的解法,就是通过反向递推找到元素编号,时间复杂度可以达到O(n)。

  • 做法其实很简单,每次删除一个人后,从下一个报数的人开始重新编号,这个时候,你可以得到原始编号和新编号的映射关系,通过这个关系,就能够方向递推达到最后要删除人的编号。

  • 但是要如何找到这个递推式子?我们来看看实际的例子。
    假设:n = 8, m = 3。设y为原始编号, x为新编号
    原始序列:
      x = 1 2 3 4 5 6 7 8
      y = 1 2 3 4 5 6 7 8
      个数:8
    新序列:
      x = 6 7 Del 1 2 3 4 5
      y = 1 2 4 5 6 7 8
      个数:7
    接下去,你只要找到x和y之间的映射关系就行了。
    怎么找?画个坐标轴看看,其实就是一个分段函数,我这里就不画了,有时间补上。
    其实映射关系是:y = (x + m) % i
    有这个映射关系,接下去只需要知道x = 1时的值,并知道m的值,然后i从1推到n,最后得到的y值,就是最后要找的值。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值