码迷,mamicode.com
首页 > 编程语言 > 详细

剑指Offer解题报告(Java版)——约瑟夫环 45

时间:2015-05-03 20:28:43      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

? ?

引言

? ?

常见的约瑟夫环问题有用循环链表做的,有用数组做的,这里提供一个用数学公式做的,由此可见,很多计算机的问题如果最终用到数学的知识,时间复杂度会大大的降低

? ?

分析问题

? ?

首先我们对0n-1删除第一个数进行分析,第一个被删除的数一定是序号为m-1的数,因为0号数了1,1号数了2,m-1号数了m,那么应该删掉m-1号,设m-1号是第k号,这里这样做是因为后面可以扩展,想扩展为m-1%n=k

? ?

剩下的数按照序列重排序如下

技术分享

? ?

因为删掉的是k,那么下面第一个就是k+1了,这个很好理解

? ?

假设我们设f函数的输出是原来的在n个数中,每次数m下,最后留下的数

? ?

而现在删掉了k,只有n-1个数了,每次数m下,最后留下的数是f‘(n-1,m)

? ?

技术分享

? ?

如何建立ff‘之间的关系呢

? ?

我们对重排序之后的数做一个映射

? ?

技术分享

? ?

该映射为

p(x) -- > y ::: y=(x-k-1)%n

? ?

则映射完之后就跟原来的问题一样了,也就是f(n-1,m)了

? ?

也就是p(f‘(n-1,m)=f(n-1,m)

? ?

而我们现在只有f(n,m)和f‘(n-1,m)之间的关系

? ?

所以我们还需要再转换一下,也就求映射的逆

? ?

技术分享

? ?

而映射p的逆映射为

? ?

o(y) -- >x x=(y+k+1)%n

? ?

其中k可以替换 k%n=(m-1)%n

? ?

o(y) -- >x x=(y+m)%n

? ?

对应到之前f(n-1,m)f‘(n-1,m)之间的关系

? ?

f‘(n-1,m)=f(n-1,m)+m%n

? ?

? ?

f(n,m)=f‘(n-1,m)

? ?

这样我们有f(n,m)f‘(n-1,m)之间的关系,也有f(n-1,m)f‘(n-1,m)之间的关系

? ?

带入之前的式子推到得到

? ?

技术分享

? ?

解决问题

? ?

static int lastRemain(int n, int m) {

int last = 0;

if (n < 1 || m < 1) {

return -1;

}

for (int i = 2; i <= n; i++)

last = (last + m) % i;

return last;

}

? ?

剑指Offer解题报告(Java版)——约瑟夫环 45

标签:

原文地址:http://www.cnblogs.com/keedor/p/4474536.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!