约瑟夫环算法的几种实现方式,最简单方式,一行代码实现

简介:
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。
分析:
(1)由于对于每个人只有死和活两种状态,因此可以用布尔型数组标记每个人的状态,可用true表示死,false表示活。
(2)开始时每个人都是活的,所以数组初值全部赋为false。
(3)模拟杀人过程,直到所有人都被杀死为止。
1.使用链表循环遍历的形式
   n代表多少个人,m代表编号为M的人:
    public int josephRing1(int n, int m) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            list.add(i);
        }
        int bt = 0;
        while (list.size() > 1) {
            //// 删除为m-1的人(从0开始)
            //解析看前面
            bt = (bt + m - 1) % list.size();
            list.remove(bt);
        }
        return list.size() == 1 ? list.get(0) : -1;
    }

2.使用递推公式

n代表多少个人,m代表编号为M的人:

 

public int josephRing2(int n, int m) {
        if (m < 1 || n < 1)
            return -1;
        int last = 0;
        // i代表有目前有几个人
        for (int i = 2; i <= n; i++)
            last = (last + m) % i;
        return last;
    }

 

3.使用递归调用

public int josephRing3(int n, int m) {
        if (n == 1) return n;
        return (josephRing3(n - 1, m) + m) % n + 1;
    }

4.最简单的实现方式,一行代码实现

 public int josephRing(int n, int m) {
        return n == 1 ? n : (josephRing(n - 1, m) + m) % n + 1;

    }

 

 

 
posted @ 2019-09-12 15:00  金万强  阅读(919)  评论(0编辑  收藏  举报