程序员面试题精选100题(14)-圆圈中最后剩下的数字

题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。

思路:最初有0,1,2,3...m-1,m,m+1,m+2...n-1这么多个数,
第一次以后变成了0,1,2,3...m-1 ,m+1,m+2...n-1

第一个被删除的数字为m%n - 1 记为k (数组的位置需要-1)

而这个时候数组的起始位置发生了变化
k+1----0
k+2----1
...
n-1 --- n-k-2
0 ---- n-k-1
....
x----x-k-1
...
k-1 ---- n-2

所以这个映射为p(x)=(x-k-1)%n;----%n可以体现循环思想
p-1(x)=(x+k+1)%n;----逆运算

设f(n,m)可以计算出最终的结果
f'(n-1,m)为第一次删除后的序列,因为序列和以前不同,但是规则相同
f'(n-1,m)计算的结果经过映射后也可以得到和f(n,m)相同的结果
所以f'(n-1,m)=p-1(f(n-1,m))=[f(n-1,m)+k+1]%n 再把k=m%n-1代入
=[f(n-1,m)+m%n-1+1]%n=[f(n-1,m)+m]%n


当n=1时,也就是序列中开始只有一个数字0,那么很显然最后剩下的数字就是0。我们把这种关系表示为:

0 n=1
f(n,m)={
[f(n-1,m)+m]%n n>1

//其实非递归的方式容易理解些,实质上就是把余下的n-1个数字入栈,然后再做同样的事情
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值