iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java环形链表(图文详解)
  • 544
分享到

Java环形链表(图文详解)

java链表数据结构算法 2023-09-30 14:09:23 544人浏览 安东尼
摘要

目录 一、判断链表中是否有环 (1)题目描述 (2)题解 二、环形链表的入环节点 (1)题目描述 (2)题解 一、判断链表中是否有环 (1)题目描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通

目录

一、判断链表中是否有环

(1)题目描述

(2)题解

二、环形链表的入环节点

(1)题目描述

(2)题解


一、判断链表中是否有环

(1)题目描述

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例:

输入:head = [3,2,0,-4],pos = 1

输出:true(节点有环)

(2)题解

思路分析:我们可以使用快慢指针来分析这个问题。

首先定义fast、slow指向head

快指针fast一次走两步、慢指针slow一次走一步

如果链表中无环,fast最终会指向null,若链表中有环,在fast和slow都进入环中后,由于fast每次比slow多走一步,fast最终会追上slow

代码实现:

public class Solution {    public boolean hasCycle(Listnode head) {        //先判断特殊情况        //若链表中为空或链表中只有一个元素,        // 则链表中无环        // 直接返回false        if (head == null || head.next == null) {            return false;        }        //定义快指针和慢指针        ListNode fast = head;        ListNode slow = head;        while (fast != null && fast.next != null) {            fast = fast.next.next;//fast一次走两步            slow = slow.next;//slow一次走一步            if (fast == slow) {//fast与slow相遇,表明链表带环                return true;            }        }        //fast指向空或指向尾节点,表明链表不带环        return false;    }}

思考:

while条件中,能否修改为 while(fast.next != null && fast != null) ?

不能,&&(逻辑与)操作符从左到右进行判断,当左边为false时,右边的表达式不会进行运算,直接返回false,只有当左边表达式为true时,才会运算右边的表达式,若右边表达式为true,则返回true

在while条件中,应先判断fast的指向是否为空,若fast的指向为空,则不能够通过fast.next访问下一个节点,否则会抛出NullPointerException(空指针异常)。因此,while (fast != null && fast.next != null),当fast指向null时,直接返回false,而不再执行fast.next

当fast走两步,slow走一步时,fast能够追上slow,当fast走三步、四步...时能否追上slow ?

当链表无环时,fast走两步、三步...都能判断链表无环

当链表有环时,我们假设fast每次走 x ( x >= 2 )步,head到入环节点有a个节点(从head到入环节点需要走a步),环上一共有C个节点,当slow走到入环节点时,fast与slow相距N0 <= N < C)个节点

当N = 0时,fast与slow直接在入环节点相遇,因此我们考虑N > 0 且 N < C 的情况

当slow走到入环节点时,此时就是我们常说的追及问题,追及问题的公式:

追及时间(次数) = 路程差 / 速度差

我们设追及次数(即fast走多少次追上slow)为m,fast与slow之间的路程差为N,速度差为x-1,则m = N / x-1,

当x = 2时,m = N,即fast走N次就能追上slow,

当x = 3时,m = N / 2,当N为偶数时,fast 走N/2次能够追上slow;当N为奇数时,fast走了(N-1)/ 2次之后,此时fast与slow的距离为1,由于fast走三步,slow走一步,fast会反超slow 1 步

此时fast与slow的距离N变为C-1,fast重新开始追及slow,若C-1为偶数,则经过 (C-1)/2次后,fast追上slow;若C-1为奇数,在fast与slow距离为1时,fast再次反超slow,fast与slow之间的距离再次变为C-1,fast再次追及slow...如此循环,fast永远追不上slow

 因此,我们可以看出,当fast一次走三步,slow一次走一步时,fast不一定能追上slow

当fast一次走四步,slow一次走一步时,分析思路与fast一次走三步一致,fast可能反超slow一步或两步,此时fast与slow的距离变为C-1 或 C-2,然后继续分情况分析

当fast走三步,slow走两步,或是fast走四步,slow走三步时,情况又如何呢 ?

由追及时间(次数) = 路程差 / 速度差,可以得出

当fast走三步,slow走两步 或是 fast一次走四步,slow一次走三步,fast与slow的速度差都为1,fast一定能追上slow,但

当fast一次走两步,slow一次走一步,slow走的总路程为N,即fast在一圈以内,能够追上slow

而当fast一次走三步,slow一次走两步时,slow走的总路程为2*N(2*N可能大于C),因此fast不一定在一圈之内追上slow

本题来自:

141. 环形链表 - 力扣(LeetCode)

二、环形链表的入环节点

(1)题目描述

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改链表

示例

输入:head = [1,2],pos = 0

输出:返回索引为0的链表节点

(2)题解

思路分析:在判断链表是否有环中,我们使用快慢指针的方法来判断链表中是否有环。fast一次走两步,slow一次走一步,若链表有环,fast一定能在环中追上slow。基于这个结论,我们可以继续推出另一个结论:从头节点出发的指针会和从fast、slow相遇节点出发的指针相遇与入环节点(证明在最后)

因此,找到入环节点:

判断链表是否有环,无环返回null,有环找到fast与slow相遇的节点

让两个指针,分别从头节点、相遇点出发,当两指针汇合时,即为链表的入环节点

代码实现:

public class Solution {    public ListNode detectCycle(ListNode head) {        //链表为空,直接返回null        if(head == null){            return null;        }        ListNode fast = head;        ListNode slow = head;        while(fast.next != null && fast.next.next != null){            fast = fast.next.next;            slow = slow.next;            //找到fast与slow的相遇点            if(fast == slow){                //让fast从头节点出发,                //slow从相遇点出发,                fast = head;                while(fast != slow){                    fast = fast.next;                    slow = slow.next;                }//相遇节点即为入环节点                     return slow;            }        }        //链表中无环,返回null        return null;    }}

为何从头节点出发的指针一定会和从fast、slow相遇节点出发的指针汇合与入环节点?

同样,当链表有环时,我们假设head到入环节点有a个节点(从head到入环节点需要走a步),环上一共有C个节点,fast与slow相遇时,与入环节点的距离为d

当fast与slow相遇时,

fast所走的路程为 a + n*C + d

fast所走路程为什么是a + n*C + d?

a为从头节点到入环节点的距离,当a > C时,可能slow还未进环,而fast已经在环中走了很多圈了,我们假设当fast与slow相遇时,fast在环中走了n圈,因此fast所走的路程为a + n*C + d

slow所走的路程为 a + d

由于fast的速度是slow的两倍,因此

2*(a + d)= a + n*C + d,即 a = n*C - d

将n*C化为 C*(n-1) + C,式子可化为 a =C* (n-1) + C-d

a是从头节点到入环节点的距离,C - d 是 相遇节点距入环节点的距离,

a =C* (n-1) + n-d 表明,从头节点出发的指针走 a步 等于 从相遇节点开始走的指针,走(n-1)圈后回到相遇点,再走n - d的距离,即从头节点出发的指针和从fast、slow相遇节点同时出发的指针最终会在入环节点处相遇

题目来自:

142. 环形链表 II - 力扣(LeetCode)

来源地址:https://blog.csdn.net/2301_76161469/article/details/133188387

--结束END--

本文标题: Java环形链表(图文详解)

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

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

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

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

下载Word文档
猜你喜欢
  • Java环形链表(图文详解)
    目录 一、判断链表中是否有环 (1)题目描述 (2)题解 二、环形链表的入环节点 (1)题目描述 (2)题解 一、判断链表中是否有环 (1)题目描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通...
    99+
    2023-09-30
    java 链表 数据结构 算法
  • 算法141. 环形链表
    1. 题目描述给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。示例 1:输入:head = [3,2,0,-4...
    99+
    2023-06-03
  • Python实现环形链表
    本文实例为大家分享了Python实现环形链表的具体代码,供大家参考,具体内容如下 我们将单向链表的最后一个节点的指针指向链表的头部(第一个节点),那么就形成了一个环形链表。环形节点可...
    99+
    2024-04-02
  • Java用单向环形链表来解决约瑟夫环Josepfu问题
    简单介绍 如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点。 单向环形链表应用场景:Josephu(约瑟...
    99+
    2024-04-02
  • 【链表问题】环形单链表约瑟夫问题
    前言以专题的形式更新刷题贴,欢迎跟我一起学习刷题,相信我,你的坚持,绝对会有意想不到的收获。每道题会提供简单的解答,如果你有更优雅的做法,欢迎提供指点,谢谢【题目描述】【要求】输入:一个环形单向链表的头节点 head 和报数 m.返回:最后...
    99+
    2023-06-02
  • Python如何实现环形链表
    这篇文章主要介绍“Python如何实现环形链表”,在日常操作中,相信很多人在Python如何实现环形链表问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python如何实现环形链表”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-30
  • Go中怎么遍历环形链表
    在Go中遍历环形链表可以通过两种方法实现: 快慢指针法:使用两个指针,一个慢指针每次移动一步,一个快指针每次移动两步。如果链表中有...
    99+
    2024-04-03
    Go
  • Java单链表反转图文教程
    目录前言背景回顾通过循环遍历方式实现链表反转通过递归方式实现链表反转递归方式反转链表问题排查与延伸问题定位问题延伸:探究Java方法调用中的参数传递实质正确的递归方式实现链表反转总结...
    99+
    2024-04-02
  • C语言数据结构之双链表&循环链表&静态链表详解
    目录单链表 VS 双链表双链表双链表的初始化(带头结点)双链表的插入双链表的删除双链表的遍历循环单链表循环双链表循环双链表的初始化循环双链表的插入循环双链表的删除静态链表什么是静态链...
    99+
    2024-04-02
  • Java数据结构与算法之双向链表、环形链表及约瑟夫问题深入理解
    目录一、双向链表二、环形链表及其应用:约瑟夫问题环形链表图示构建一个单向的环形链表思路遍历环形链表约瑟夫问题一、双向链表 使用带head头的双向链表实现 - 水浒英雄排行榜管理单向链...
    99+
    2024-04-02
  • python双向循环链表实例详解
    使用python实现双向循环链表,供大家参考,具体内容如下 双向循环链表: 将所有的数据存放到节点中,每一个节点相连接,首尾链接,每一个节点中有一个数据存储区,和两个链接区,一个链接...
    99+
    2024-04-02
  • python单向循环链表实例详解
    使用python实现单向循环链表,供大家参考,具体内容如下 单向循环链表 将所有的链接在一起,每一个节点分为数据存储区和链接区,数据区存储数据,链接区链接下一个节点 item: 存储...
    99+
    2024-04-02
  • Java数据结构与算法系列精讲之环形链表
    目录概述链表环形链表环形链表实现Node 类insert 方法remove 方法main完整代码概述 从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章....
    99+
    2024-04-02
  • Python数据结构之循环链表详解
    目录0. 学习目标1. 循环链表简介2. 循环单链表实现2.1 循环单链表的基本操作2.2 简单的实现方法2.3 循环单链表应用示例2.4 利用循环单链表基本操作实现复杂操作3. 循...
    99+
    2024-04-02
  • java基于双向环形链表解决丢手帕问题的示例分析
    这篇文章主要为大家展示了“java基于双向环形链表解决丢手帕问题的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java基于双向环形链表解决丢手帕问题的示例分析”这篇文章吧。具体如下:问...
    99+
    2023-05-30
    java
  • Android形状图形与状态列表图形及九宫格图片超详细讲解
    目录一、图形Drawable二、形状图形三、九宫格图片四、状态列表图形一、图形Drawable Drawable类型表达了各种各样的图形,包括图片、色块、画板、背景等。 包含图片在内...
    99+
    2024-04-02
  • Java复杂链表的复制详解
    目录1.题目2.解法2.1 拼接+拆分3.代码1.题目 请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,...
    99+
    2024-04-02
  • Java数据结构之链表详解
    目录一、链表的介绍二、单链表的实现三、双向链表的实现四、循环链表的实现五,链表相关的面试题一、链表的介绍 什么是链表 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑...
    99+
    2024-04-02
  • Java 在 Excel 中创建饼图/环形图
    饼图是Excel中常见的一种圆饼形图表工具,它能够直接以图形的方式展现各个组成部分在整体中所占的比例,从而帮助我们更加快速直观的去分析和理解抽象的数据。而环形图则是饼图的一种变形,在视觉上,环形图去掉了中心的部分,但其主要功能依旧是诠释数据...
    99+
    2023-06-02
  • C语言实现带头双向环形链表
    双向循环链表 上一次我们讲了单向无头非循环链表的实现,单向无头非循环链表的特点是:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构。而带头双向循环链表则恰恰与无...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作