看小朋友做游戏顿时解决了约瑟夫问题

简介: 看小朋友做游戏顿时解决了约瑟夫问题

环形链表

认识单向环形链表


这里我们以单向环形链表为例子


就是我们最后一个节点的next域指向头结点,形成闭环

1.png



引用场景以及问题


Josephu(约瑟夫、约瑟夫环) 问题

Josephu 问题为:设编号为 1,2,… n 的 n 个人围坐一圈,约定编号为 k(1<=k<=n)的人从 1 开始报数,数 到 m 的那个人出列,它的下一位又从 1 开始报数,数到 m 的那个人又出列,依次类推,直到所有人出列为止,由


此产生一个出队编号的序列。

2.png


思路提示:


提示:用一个不带头结点的循环链表来处理 Josephu 问题:先构成一个有 n 个结点的单循环链表,然后由 k 结 点起从 1 开始计数,计到 m 时,对应结点从链表中删除,然后再从被删除结点的下一个结点又从 1 开始计数,直 到最后一个结点从链表中删除算法结束。


Josephu 问题解题思路

认识约瑟夫问题,以及我们想要实现的场景,


编写实现 单向环形链表

约瑟夫问题的要求 根据区间报数 报数的小孩出列

coding 出我们需要的需求

3.png


实现单向循环链表


思路

大体上和我们的单向链表有雷同的地方,区别在于:


我们需要在创建链表的时候将尾结点的最后一个指向头结点,这也就意味着我们需要有至少两个指针来记录头尾节点。

遍历的方式也要有些许的变化,结束循环的条件从head.next = null改变成CurBoy.next(指向尾部节点的指针) = first;最后为头节点的时候遍历为第二个

4.png


我们简单的先创建一个实现链表需要的节点对象


约瑟夫问题环形链表的节点


//环形链表 约瑟夫问题 节点
class Boy {
    private int No;
    private Boy Next;
    public Boy(int no) {
        this.No = no;
    }
    public int getNo() {
        return No;
    }
    public void setNo(int no) {
        No = no;
    }
    public Boy getNext() {
        return Next;
    }
    public void setNext(Boy next) {
        Next = next;
    }
}

创建环形链表对象实现生成链表和遍历链表,以及解决约瑟夫问题的方(具体的实现思路见代码注释)


// 环形单向链表
class CircleSingleLinkeList {
    Boy first = null;
    /**
     * @author 冷环渊 Doomwatcher
     * @context: 一个环形链表  参数是这个链表有多少节点
     * @date: 2021/12/21 15:47
     * @param nums
     * @return: void
     */
    public void CreateListNode(int nums) {
        if (nums < 1) {
            System.out.println("无法开始游戏,因为链表小于最小的游戏节点数量");
            return;
        }
        // 创建一个 辅助之间用于遍历和指向节点
        Boy curBoy = null;
        for (int i = 1; i <= nums; i++) {
            Boy boy = new Boy(i);
            //如果只有一个节点的话 也可以生成环形链表
            if (i == 1) {
                first = boy;
                first.setNext(first);
                curBoy = first;//将辅助指针指向链表的第一个节点 形成闭环
            } else {
                //    如果不是一个的话就生成多个节点
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }
    public void showListBoy() {
        if (first == null) {
            System.out.println("链表为空,不能遍历");
            return;
        }
        //   frist 节点不能移动 我们创建一个指针
        Boy curboy = first;
        while (true) {
            System.out.printf("小孩的编号是: %d \n", curboy.getNo());
            // 说明已经遍历完毕
            if (curboy.getNext() == first) {
                break;
            }
            //后移 curboy
            curboy = curboy.getNext();
        }
    }
    /**
     * @author 冷环渊 Doomwatcher
     * @context: 这里我们以小孩做游戏来解决约瑟夫问题,
     * @date: 2021/12/22 21:16
     * @param nums 一共有多少个小孩
     * @param start 从那个小孩开始报数
     * @param index 每隔几个小孩报数一次
     * @return: void
     */
    public void JosephuFunc(int nums, int start, int index) {
        if (first == null || start < 1 || start > nums) {
            System.out.println("参数不对,请重新输入参数");
            return;
        }
        Boy helper = first;
        //将 helper遍历到最后一个节点
        while (true) {
            if (helper.getNext() == first) {
                break;
            }
            helper = helper.getNext();
        }
        // 小孩子 报数之前,要遍历指针到从start开始的小孩的节点
        for (int i = 0; i < start - 1; i++) {
            first = first.getNext();
            helper = helper.getNext();
        }
        //当小孩报数的时候 让 first和helper 同时移动m-1次 然后出圈
        //这里循环操作 知道圈中的一个节点
        while (true) {
            //说明列表只有一个节点
            if (helper == first) {
                break;
            }
            //循环之后将 指针后移
            for (int i = 0; i < index - 1; i++) {
                first = first.getNext();
                helper = helper.getNext();
            }
            //    这个时候 first选中的节点就是要出圈的小孩
            System.out.printf("小孩 %d 出圈\n", first.getNo());
            //出圈操作
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.printf("最后剩下的小孩 %d \n", first.getNo());
    }
}

实现结果

1.png


相关文章
|
BI C# C++
C# 机房重构——VS2017中没有报表控件(ReportView)
C# 机房重构——VS2017中没有报表控件(ReportView)
390 0
|
网络架构
交换机与路由器技术-31-扩展ACL
交换机与路由器技术-31-扩展ACL
185 0
|
3天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23287 2
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
5天前
|
人工智能 API 开发工具
Claude Code国内安装:2026最新保姆教程(附cc-switch配置)
Claude Code是我目前最推荐的AI编程工具,没有之一。 它可能不是最简单的,但绝对是上限最高的。一旦跑通安装、接上模型、定好规范,你会发现很多原本需要几小时的工作,现在几分钟就能搞定。 这套方案的核心优势就三个字:可控性。你不用依赖任何不稳定服务,所有组件都在自己手里。模型效果不好?换一个。框架更新了?自己决定升不升。 这才是AI时代开发者该有的姿势——不是被动等喂饭,而是主动搭建自己的生产力基础设施。 希望这篇保姆教程,能帮你顺利上车。做出你自己的作品。
7666 18
Claude Code国内安装:2026最新保姆教程(附cc-switch配置)
|
12天前
|
缓存 人工智能 自然语言处理
我对比了8个Claude API中转站,踩了不少坑,总结给你
本文是个人开发者耗时1周实测的8大Claude中转平台横向评测,聚焦Claude Code真实体验:以加权均价(¥/M token)、内部汇率、缓存支持、模型真实性及稳定性为核心指标。
4635 24
|
8天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
3267 11
|
7天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
2669 8
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病