IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构-链表带环问题 #经典题# -> 正文阅读

[数据结构与算法]数据结构-链表带环问题 #经典题#

一、问题描述

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。在这里插入图片描述
其中pos为圆环的入口点序号,但返回值并不是用pos,返回节点地址。

二、如何判断链表是否带环

假设链表带环,那么这个链表就会一直循环下去;假设这个链表没有环,那么这个链表最终就会走到空。基于此,我们定义两个指针(快慢指针),fast与slow。循环一直往后走,当fast为空或者fast->next为NULL时,代表无环;当fast==slow时,即相遇,即有环。

#fast和slow每次走几步合适#
在这里插入图片描述

slow很明显每次只走一步最合适,那么fast该走几步,是否一定能相遇?
首先,当fast进环时,slow走到了L的中点。如下图:
在这里插入图片描述

此后,fast开始转圈圈,当slow开始进环,fast可能在环内任意一点。然后fast开始追逐slow。(思考:为什么在slow的一圈之内,fast必追上slow?)
如果fast一次走2步,fast和slow必能一圈之内相遇。因为速度差为1,他们之间的距离每次缩减1,所以必能相遇。

如果fast一次走3步,这里就要分情况讨论:
在这里插入图片描述此时fast和slow相距C-X,距离依次减小:
第一圈:
C-X
C-X-2
C-X-4

0或者-1
当走到最后一步为0,则能相遇;为-1,代表反超,错过。即C-X为偶数时能相遇,否则不能。继续考虑第二圈是否能追上。

第二圈:
在这里插入图片描述此时fast比slow快1,距离为C-1。此时按每步距离减2
C-1
C-3
C-5

0/-1
同理,当最后一步为0,则能相遇;为-1,代表反超,错过,而此次错过则为永远错过。(因为接下来距离又会变成C-1)。所以当C-1为偶数时,第二圈能遇见,否则,永远不可能相遇。

三、如何求进环点

1、这里先给出结论:
在这里插入图片描述
如图所示,假设meet为相遇点,则一个指针从head开始走,一个指针从meet开始走,一定会在进环点相遇。接下来给出证明。

2、结论证明:
在这里插入图片描述相遇时slow走的距离:L+X
fast走的距离:NC+L+X
有NC+L+X = 2(L+X)----->L = NC-X ------>L = (N-1)C+C-X
注意:这里N代表N圈,由于不知道圈C和L的大小,所以无法判断在相遇前,fast转了多少圈。
L = (N-1)C+C-X 可知两指针head和meet必会在进环口相遇。

四、代码实现

struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next)     //fast和fast->next的顺序不能反
    {                             //不然就会出现访问空指针的情况
        slow = slow->next;
        fast = fast->next->next;
        if(fast == slow)         //有环
        {
            struct ListNode* meet = fast;   //相遇点
            while(meet != head)
            {
                meet = meet->next;
                head = head->next;
            }
            return meet;
        }
    }
    return NULL;
}

五、总结

该题主要考察的逻辑推导能力,和数学找规律类似,读者重心应该放在推导上。该题代码量较少,对大家来说都不是问题,特别注意我代码里面的备注。

tip:写的不好的希望大家补充指正,出现争论,一定是你对。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:47:48  更:2021-09-04 17:48:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 0:52:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码