原题(Medium): 

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

  为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

  说明:不允许修改给定的链表。

  

思路:

  首先要考虑的就是怎么发现一个链表是否有环,一个比较普遍的解法就是:快慢指针,定义两个指针:一个快指针,快指针每次跨链表的两个节点;一个慢指针,慢指针每次指向下一个节点。如果链表有环,那么两指针迟早会相遇,从而发现有环而结束比遍历,如果没指针,快指针就会到达链表尾部而结束遍历。

  接下来就是难点了,如何找到入环的节点,我们假设入环的节点与链表的首节点距离为a,然后假设入环的节点与快慢指针相遇的那个结点的距离为b,那么在两指针相遇时,我们可以知道快指针走过的距离为a+x圈+b,而慢指针走过的距离为a+y圈+b,且有一个重要的信息就是,在两指针相遇时,快指针走过的距离是慢指针的两倍。就是说a+x+b  = 2(a+y+b) 还有一个条件就是快指针比慢指针多走的路程一定是环长的整数倍(假设是n倍),这是肯定的,因为a的长度两个节点都会走,那么快指针比慢指针多出来的长度就是快的比慢的多走很多圈,即2(a+y+b)  - (a+y+b)  = a+b+y圈 = n 圈:入环节点与链表的首节点距离(a)+入环节点到相遇点之间的距离(b)是环的整数倍(n - y圈),现在我们知道两个指针都在离入环节点距离为b的那个相遇点,而现在a+b是环长度的整数倍,就是说如果慢指针再走a步,就等于慢指针再走了一次a+b的路程,(1圈也好,n圈也好,都是)回到了入环结点的位置,但是问题是,我们不知道a是多少啊?

  我们可以再定义一个指针指向首节点,该指针走a步的同时慢指针也走a步,两者就相遇啦,相遇的节点就是入环节点。

 ListNode *detectCycle(ListNode *head) {
if (head == NULL) return NULL;
ListNode* fast = head;
ListNode* slow = head;
bool hasCycle = false;
//首先,快慢指针判断是否有环
while (fast&& fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
hasCycle = true;
break;
}
}
//没环,结束
if (!hasCycle) return NULL;
//有环,两指针同时走,必在a步后相遇,相遇点为入环节点
ListNode* q = head;
while (q != slow)
{
q = q->next;
slow = slow->next;
}
return q;
}

LeetCode | 142. 环形链表 II的更多相关文章

  1. LeetCode 142. 环形链表 II(Linked List Cycle II)

    142. 环形链表 II 142. Linked List Cycle II 题目描述 给定一个链表,返回链表开始入环的第一个节点.如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整 ...

  2. Java实现 LeetCode 142 环形链表 II(二)

    142. 环形链表 II 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始 ...

  3. Leetcode 142.环形链表II

    环形链表II 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶:你是否可以不用额外空间解决此题? 链表头是X,环的第一个节点是Y,sl ...

  4. LeetCode 142——环形链表 II

    1. 题目 2. 解答 2.1 方法 1 定义快慢两个指针,慢指针每次前进一步,快指针每次前进两步,若链表有环,则快慢指针一定会相遇. 当快慢指针相遇时,我们让慢指针指向头节点,快指针不变,然后每次快 ...

  5. LeetCode 142——环形链表II(JAVA)

    给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...

  6. LeetCode 142. 环形链表 II(Linker List Cycle II)

    题目描述 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶: 你是否可以不用额外空间解决此题? 解题思路 分为三步: 首先判断是否存在 ...

  7. leetcode 142. 环形链表 II(c++)

    给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...

  8. 【LeetCode】142. 环形链表 II

    142. 环形链表 II 知识点:链表:set:快慢指针 题目描述 给定一个链表,判断链表中是否有环. 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表 ...

  9. Leetcode.142-Linked-list-cycle-ii(环形链表II)

    环形链表II 思路 https://www.cnblogs.com/springfor/p/3862125.html https://blog.csdn.net/u010292561/article/ ...

随机推荐

  1. 简易配置中心Confd入手

    改成动态更新配置文件,如下每五秒重新生成配置文件 confd与etcd的使用 Add keys This guide assumes you have a working etcd, or consu ...

  2. python中序列的操作

    Python中的序列操作 可变对象:列表.字典.集合 不可变对象:数值.字符串.元组.forzenset 1.序列的通用操作 (1)测试元素是否存在 x in S和x not in S,返回True或 ...

  3. vue解决大文件断点续传

    一.概述 所谓断点续传,其实只是指下载,也就是要从文件已经下载的地方开始继续下载.在以前版本的HTTP协议是不支持断点的,HTTP/1.1开始就支持了.一般断点下载时才用到Range和Content- ...

  4. Windbg的命令

    前面介绍了Windbg的UI功能,也基本上能完成基本的调试任务,但是WinDBG主要是以命令方式工作的,这些命令在Command Window里输入.WinDBG共支持三类命令:标准命令.元命令和扩展 ...

  5. centos gcc 新版本安装的一种方法

    最近出来一个v 语言,打算试用下,但是需要编译,centos 7 gcc 版本太低,一种可选的解决方法 使用Software Collections Software Collections 安装方法 ...

  6. Glider(前缀和+二分)

    题目链接:Glider Gym-101911B 解题分析:下落的高度一定,是h.在没有气流的地方每秒下落1:所以可以转化为经过无气流地带的时间总长为h. 那么很显然从一个有气流地带的开始,选择下落,那 ...

  7. Clouds Classification from Sentinel-2 Imagery with Deep Residual Learning and Semantic Image Segmentation

    哨兵2号云检测的语义分割,提出了CloudNet,不使用池化和上采样操作,从头到尾保持原图大小,中间每个块使用ASPP和残差连接,网络结构如下 比较了CNN, FCN, DeeplabV3+,效果都没 ...

  8. ranger整合kerberos

    一.生成主体 在kerberos服务器生成用于ranger的用户主体: # kadmin.local addprinc -randkey HTTP/manager1@HADOOP.COM addpri ...

  9. MySQL的ROUND函数

    ROUND(X) ROUND(X,D) 返回参数X, 其值接近于最近似的整数.在有两个参数的情况下,返回 X ,其值保留到小数点后D位,而第D位的保留方式为四舍五入.若要接保留X值小数点左边的D 位, ...

  10. @submit.native.prevent作用

    <el-form :inline="true" :model="geCarManageData" class="demo-form-inline ...