首页 > 其他 > 详细

josephus问题

时间:2014-03-11 11:13:22      阅读:287      评论:0      收藏:0      [点我收藏+]

问题描述

n个人围成一圈,号码为1-n,从1开始报数,报到2的退出,剩下的继续从1开始报数,求最后一个人的号码。

算法分析

最直观的算法是用循环链表模拟。从首节点开始,不断删除第二个节点,直到只剩一个节点为止。时间复杂度是O(2n).

bubuko.com,布布扣
typedef struct josephusnode{
    struct josephusnode *next;
    int item;
}jnode;

int listjosephus(jnode *head){
    jnode *n = head;
    while(n->next!=n){
        jnode *t = n->next;
        n->next = t->next;
        n = n->next;
        free(t);
    }
    int retv = n->item;
    free(n);
    return retv;
}
bubuko.com,布布扣

更简单的方法是数学推导。Donald E. Knuth的《具体数学》有很详细精彩的推导过程,Josephus数具有这样的递归式:

j(1)=1

j(2n)=2j(n)-1

j(2n+1)=2j(n)+1

总结发现j(2m+n)=2n+1,代码很简单:

bubuko.com,布布扣
int mathjosephus(int n){
    int x=n, y=n;
    while(n){
        y = n;
        n &= n-1;
    }
    x = ~y&x;
    x = 1+(x<<1);
    return x;
}
bubuko.com,布布扣

 

 

参考:

《具体数学》

code:

https://github.com/coderkian/algorithm/blob/master/josephus.c

josephus问题,布布扣,bubuko.com

josephus问题

原文:http://www.cnblogs.com/coderkian/p/3589987.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!