iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >【链表问题】环形单链表约瑟夫问题
  • 656
分享到

【链表问题】环形单链表约瑟夫问题

2023-06-02 19:06:57 656人浏览 安东尼
摘要

前言以专题的形式更新刷题贴,欢迎跟我一起学习刷题,相信我,你的坚持,绝对会有意想不到的收获。每道题会提供简单的解答,如果你有更优雅的做法,欢迎提供指点,谢谢【题目描述】【要求】输入:一个环形单向链表的头节点 head 和报数 m.返回:最后

前言

以专题的形式更新刷题贴,欢迎跟我一起学习刷题,相信我,你的坚持,绝对会有意想不到的收获。每道题会提供简单的解答,如果你有更优雅的做法,欢迎提供指点,谢谢

【题目描述】

【链表问题】环形单链表约瑟夫问题

【要求】

输入:一个环形单向链表的头节点 head 和报数 m.

返回:最后生存下来的节点,且这个节点自己组成环形单向链表,其他节点都删除掉。

【难度】

士:★☆☆☆

【解答】

方法1:时间复杂度为 O( n * m)

这道题如果不考虑时间复杂度的话还是挺简单的,就遍历环形链表,每遍历 m 个节点就删除一个节点,知道链表只剩下一个节点就可以了。

代码如下

 1    //时间复杂度为O(n*m)的解决方法
2    public static node josephusKill(Node head, int m) {
3        if(head == null || m < 1)
4            return head;
5        Node last = head;
6        //定位到最后一个节点
7        while (head.next != last) {
8            head = head.next;
9        }
10        int count = 0;
11        while (head.next != head) {
12            if (++count == m) {
13                head.next = head.next.next;
14                count = 0;
15            } else {
16                head = head.next;
17            }
18        }
19        return head;
20    }

由于有些手机可能会出现乱码问题,我这里再贴出图片:

【链表问题】环形单链表约瑟夫问题

这个方法的时间复杂度为 O(n * m)。下面用时间复杂度为方法解决。

方法二:时间复杂度为 O(n)

这个方法的难度为:

校:★★★☆

我们可以给环形链表的节点编号,如果链表的节点数为 n, 则从头节点开始,依次给节点编号,即头节点为 1, 下一个节点为2, 最后一个节点为 n.

我们用 f(n) 表示当环形链表的长度为n时,生存下来的人的编号为 f(n),显然当 n = 1 时,f(n) = 1。假如我们能够找出 f(n) 和 f(n-1) 之间的关系的话,我们我们就可以用递归的方式来解决了。我们假设 人员数为 n, 报数到 m 的人就自杀。则刚开始的编号为

m - 2

m - 1

m

m + 1

m + 2

进行了一次删除之后,删除了编号为m的节点。删除之后,就只剩下 n - 1 个节点了,删除前和删除之后的编号转换关系为:

删除前     ---     删除后

…          ---      …

m - 2     ---     n - 2

m - 1    ---      n - 1

m         ----    无(因为编号被删除了)

m + 1     ---     1(因为下次就从这里报数了)

m + 2     ----     2

…         ----         …

新的环中只有 n - 1 个节点。且编号为 m + 1, m + 2, m + 3 的节点成了新环中编号为 1, 2, 3 的节点。

假设 old 为删除之前的节点编号, new 为删除了一个节点之后的编号,则 old 与 new 之间的关系为 old = (new + m - 1) % n + 1。

注:有些人可能会疑惑为什么不是 old = (new + m ) % n 呢?主要是因为编号是从 1 开始的,而不是从 0 开始的。如果 new + m == n的话,会导致最后的计算结果为 old = 0。所以 old = (new + m - 1) % n + 1.

这样,我们就得出 f(n) 与 f(n - 1)之间的关系了,而 f(1) = 1.所以我们可以采用递归的方式来做。

代码如下:

 1   //时间复杂度为O(n)
2    public static Node josephusKill2(Node head, int m) {
3        if(head == null || m < 1)
4            return head;
5        int n = 1;//统计一共有多少个节点
6        Node last = head;
7        while (last.next != head) {
8            n++;
9            last = last.next;
10        }
11        //直接用递归算出目的编号
12        int des = f(n, m);
13        //把目的节点取出来
14        while (--des != 0) {
15            head = head.next;
16        }
17        head.next = head;
18        return head;
19    }
20
21    private static int f(int n, int m) {
22        if (n == 1) {
23            return 1;
24        }
25        return (f(n - 1, m) + m - 1) % n + 1;
26    }

图片代码:

【链表问题】环形单链表约瑟夫问题

问题拓展

对于上道题,假设是从第 K 个节点开始报数删除呢? 又该如何解决呢?

--结束END--

本文标题: 【链表问题】环形单链表约瑟夫问题

本文链接: https://www.lsjlt.com/news/231108.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【链表问题】环形单链表约瑟夫问题
    前言以专题的形式更新刷题贴,欢迎跟我一起学习刷题,相信我,你的坚持,绝对会有意想不到的收获。每道题会提供简单的解答,如果你有更优雅的做法,欢迎提供指点,谢谢【题目描述】【要求】输入:一个环形单向链表的头节点 head 和报数 m.返回:最后...
    99+
    2023-06-02
  • Java用单向环形链表来解决约瑟夫环Josepfu问题
    简单介绍 如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点。 单向环形链表应用场景:Josephu(约瑟...
    99+
    2024-04-02
  • C++实现约瑟夫环的循环单链表
    约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。. 从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人...
    99+
    2024-04-02
  • Java使用单链表实现约瑟夫环
    本文实例为大家分享了Java使用单链表实现约瑟夫环的具体代码,供大家参考,具体内容如下 构建一个单向的环形链表思路 1.先创建第一个节点, 让first指向该节点, 并形成环形 2....
    99+
    2024-04-02
  • Java数据结构与算法之双向链表、环形链表及约瑟夫问题深入理解
    目录一、双向链表二、环形链表及其应用:约瑟夫问题环形链表图示构建一个单向的环形链表思路遍历环形链表约瑟夫问题一、双向链表 使用带head头的双向链表实现 - 水浒英雄排行榜管理单向链...
    99+
    2024-04-02
  • C语言用循环单链表实现约瑟夫环
    用循环单链表实现约瑟夫环(c语言),供大家参考,具体内容如下 源代码如下,采用Dev编译通过,成功运行,默认数到三出局。 主函数: main.c文件 #include <s...
    99+
    2024-04-02
  • 约瑟夫斯问题
    弗拉维奥·约瑟夫斯(Josephus problem)是一世纪著名历史学家,他和他39个战友被罗马军队包围在洞中。他们宁愿死在洞中也不想成为罗马人得俘虏,于是他们围成了一个圈,其中一个人被指定为第一个人,顺时针报数到第七个人,这个人就会被...
    99+
    2023-01-31
    约瑟夫
  • C++约瑟夫环问题详解
    题目如下: 有一家公司,这个公司有一位老板和13名程序员,每天下班前老板都会组织他们玩一次游戏,游戏的胜利者可以不加班,失败者需要加班2小时。游戏规则如下: 一张圆桌共有13个座位,...
    99+
    2024-04-02
  • javascript循环链表之如何实现约瑟夫环
    小编给大家分享一下javascript循环链表之如何实现约瑟夫环,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!代码如下:var node = this.hea...
    99+
    2024-04-02
  • C++ 约瑟夫环问题案例详解
    在牛客网上做到一道题,是约瑟夫环的变型,所以借此学习一下新知识,并且巩固一下对题目意思的理解,这一篇仅作约瑟夫环问题的解释,下一篇再写题目: ##1.首先,我们先来了解一下什么是约瑟...
    99+
    2024-04-02
  • C++约瑟夫环问题怎么实现
    本文小编为大家详细介绍“C++约瑟夫环问题怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++约瑟夫环问题怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。题目如下:有一家公司,这个公司有一位老板和...
    99+
    2023-06-26
  • PHP怎么解决约瑟夫环问题
    这篇文章主要讲解了“PHP怎么解决约瑟夫环问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP怎么解决约瑟夫环问题”吧!约瑟夫环问题(猴子选大王)PHP版约瑟夫斯问题问题有时候也被描述成...
    99+
    2023-06-22
  • JavaScript三种方法解决约瑟夫环问题的方法
    目录概述问题描述循环链表有序数组数学递归总结概述 约瑟夫环问题又称约瑟夫问题或丢手绢问题,是一道经典的算法问题。问题描述也有很多变式,但大体的解题思路是相同的。本篇将以循环链表、有序...
    99+
    2024-04-02
  • C语言版约瑟夫问题算法实现
    1、问题描述:        有n个人围坐一圈,现从第s个人开始报数,数到m的人出列,接着从出列的下一个人开始重新报数,数到m的人又出列.如此下去,直到所有人都出列为止.试设计确定他...
    99+
    2024-04-02
  • C语言数据结构中约瑟夫环问题探究
    目录问题描述基本要求测试数据实现思路1实现思路2结果数据结构开讲啦!!! 本专栏包括: 抽象数据类型线性表及其应用栈和队列及其应用串及其应用数组和广义表树、图及其应用存储管理、查找和...
    99+
    2023-01-12
    C语言约瑟夫环 C语言约瑟夫环问题
  • C/C++经典算法之约瑟夫问题详解
    目录什么是约瑟夫问题? 方法一:数组方法二:环形链表方法三:递归总结什么是约瑟夫问题?  约瑟夫问题:n个人围成一圈,初始编号从1~n排列,从约定编号为x的人开始...
    99+
    2024-04-02
  • 详解基于C++实现约瑟夫环问题的三种解法
    目录一、前言二、循环链表模拟三、有序集合模拟四、递归公式解决五、结语一、前言 什么是约瑟夫环问题? 约瑟夫环问题在不同平台被"优化"描述的不一样,例如在牛客剑指offer叫孩子们的游...
    99+
    2024-04-02
  • C语言数据结构中约瑟夫环问题如何解决
    本文小编为大家详细介绍“C语言数据结构中约瑟夫环问题如何解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言数据结构中约瑟夫环问题如何解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。问题描述约瑟夫环问题的...
    99+
    2023-07-04
  • Java之单链表问题的示例分析
    这篇文章给大家分享的是有关Java之单链表问题的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。单链表单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表...
    99+
    2023-06-20
  • 如何实现C语言版约瑟夫问题算法
    这篇文章主要为大家展示了“如何实现C语言版约瑟夫问题算法”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何实现C语言版约瑟夫问题算法”这篇文章吧。1、问题描述:    &nb...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作