约瑟夫环-循环链表,循环队列+Java实现

题目

【问题描述】编号为1,2,3,……,n的n个人按顺时针方向围坐在一张圆桌周围。给定一个正整数m<n,从第一个人开始按顺时针方向自1开始报数,每报到m时就让其出列,且计数继续进行下去。如此下去,直到圆桌周围人全部出列为止。最后出列者为优胜者。每个人的出列次序定义了整数1,2,3,……,n的一个排列。这个排列成为一个(n,m)Josephus排列。例如:若(7,3)Josephus排列为3,6,2,7,5,1,4,对于给定的1,2,3,……,n中的K个数,Josephus想知道是否存在一个正整数m(m<n),使得Josephus(n,m)排列最后k个数恰好为事先指定的k个数。
【基本要求】利用单向循环链表存储结构模拟约瑟夫环过程,按照出列顺序输出各人编号。
【测试数据】
输入数据:n = 7,k = 4,指定排列的最后k个数为7、5、1、4。
输出数据:m的值为3。

思路

约瑟夫环:N个人围成一圈报数,报到M个数就出列,并重新从1开始报数。
回忆大二学的数据结构,模拟需用循环链表或循环队列,实现m的情况输出,再截取对比输入的排列判断得到符合的m值。没有输出-1;

循环队列

    public static int findM(int n, int k, List<Integer> lk) {
        // 约瑟夫环
        // 注意:按照出列顺序输出各人编号(队列!!!)
        // 找m的值
        for (int m = 1; m < n; m++) {
            int count = 0;
            int index = 0;
            List<Integer> res = new LinkedList<>();// 模拟圆桌
            LinkedList<Integer> queue = new LinkedList<>();// 出队队列
            // 模拟圆桌编号
            for (int i = 1; i <= n; i++) {
                res.add(i);
            }
            // 模拟出列过程(全出对比)
            while (res.size() !=0) {
                count++;
                if (count == m) {
                    count = 0;
                    queue.addLast(res.get(index));// 入队
                    res.remove(index);
                } else {
                    index = (index + 1) % res.size();// 循环实现
                }
            }
            System.out.println(queue);
            if (queue.subList(n-k,n).equals(lk)) {
                return m;
            }
        }
        return -1;
    }

循环链表

类似队列,略。
链表类:

class Node {
    int data;
    Node next;

    Node(int data) {
        this.data = data;
    }
}

循环链表关键实现:

cur.next = head; // 构建循环链表
cur = head;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值