首页 > 其他分享 >07_环形链表

07_环形链表

时间:2023-11-04 09:22:05浏览次数:57  
标签:slow 07 环形 fast 相遇 链表 节点 指针

环形链表

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

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

不允许修改 链表。

示例 1:

img

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

img

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

img

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

【思路】

主要考察两个知识点:

  1. 判断链表是够有环
  2. 如果有环,如何找到这个环的入口

判断链表是否有环

可以使用快慢指针法,分别定义fast和slow指针,从头节点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果fast和slow指针在途中相遇,说明这个链表有环。

如果有环,如何找到这个环的入口

此时已经可以判断链表是否有环了,那么接下来就找这个环的入口了。

假设从头结点到环形入口节点 的节点数为a。环形入口节点到fast指针与slow指针相遇节点节点数为b。从相遇节点再到环形入口节点节点数为b。 如图所示:

image-20231103091922120

那么相遇时: slow指针走过的节点数为: a + b, fast指针走过的节点数:a + b + n (b + c),n为fast指针在环内走了n圈才遇到slow指针, (b+c)为 一圈内节点的个数A。

因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2:

(a + b) * 2 = a + b + n (b + c)

两边消掉一个(x+y): a + b = n (b + c)

因为要找环形的入口,那么要求的是a,因为a表示头结点到环形入口节点的的距离。

所以要求a,将x单独放在左面:a= n (b + c) - b ,

再从n(b+c)中提出一个 (b+c)来,整理公式之后为如下公式:x = (n - 1) (b + c) + c 注意这里n一定是大于等于1的,因为 fast指针至少要多走一圈才能相遇slow指针。

这个公式说明什么呢?

先拿n为1的情况来举例,意味着fast指针在环形里转了一圈之后,就遇到了 slow指针了。

当 n为1的时候,公式就化解为 a = b

这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点

也就是在相遇节点处,定义一个指针index1,在头结点处定一个指针index2。

让index1和index2同时移动,每次移动一个节点, 那么他们相遇的地方就是 环形入口的节点。

本题的关键点在于:如何在判断出有环之后,从fast和slow指针相遇处出发和head出发再次相遇即为链表相交的入口处。

public class Solution {
	public ListNode detectCycle(ListNode head) {
		ListNode slow = head;
		ListNode fast = head;
		while (fast != null && fast.next != null) {
			slow = slow.next;
			fast = fast.next.next;
			if (slow == fast) {  //有环
				ListNode index1 = fast;
				ListNode index2 = head;
				// 两个指针,从头节点和相遇节点,各走一步,直到相遇,相遇点即为环入口
				while (index1 != index2) {
				index1 = index1.next;
				index2 = index2.next;
				}
				return index1;
			}
		}
		return null;
	}
}

标签:slow,07,环形,fast,相遇,链表,节点,指针
From: https://www.cnblogs.com/codingbao/p/17808884.html

相关文章

  • 顺序表和链表
    writeup后面写258.链表去重给定一个键值为整数的单链表L,将键值的绝对值有重复的结点删除:即对任意键值K,只有键值或其绝对值等于K的第一个结点被保留在L中。例如,下面单链表L包含键值21、-15、15、7、-15,如下图(a)所示;去重后的链表L包含键值21、-15、7,如......
  • 数据结构之链表
    1.简介链表(LinkedList)是一种基本的数据结构,用于表示一组元素,这些元素按顺序排列,每个元素都与下一个元素连接。与数组不同,链表的元素不是在内存中连续存储的,而是通过指针来连接的。链表由节点(Node)组成,每个节点包含两个主要部分:数据和指向下一个节点(或上一个节点,如果是双向链表)的......
  • MAX7219点阵屏四合一—基于CH32V307的应用
    参考链接:https://blog.csdn.net/weixin_46957846/article/details/127352759本篇文章为基于CH32V307的MAX7219级联应用,代码是基于上参考链接代码基础上修改,若有侵权请联系及时删除。该应用测试所用模块为一个四级级联模块,参考链接代码下载应用4个点阵模块均显示均显示同一个字符......
  • QCN9074 QCN9024|DR9074E Compatible with DR4019 Platform OpenWrt
    ExcitingNews:WallysWiFi6Card#DR9074ENowCompatiblewithDR4019Platform(WiFi5)andOpenWrtDriver-AGame-ChangerinWirelessTech!Wearethrilledtobringyousomeexcitingnews!OurWallysWiFi6DualBandCard#DR9074Ehasjusttakenagiant......
  • Java面试题:链表-合并两个排序的链表
    描述输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。示例输入:{1,3,5},{2,4,6}返回值:{1,2,3,4,5,6}原题地址:https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337代码实现packagecom.example.demo.linked;......
  • ARC078F
    这是一道容易想假的题(个人认为)。首先有一个转化,我们发现直接删边不好做,我们考虑如果已经知道这条唯一路径该怎么做。我们画完图后发现,保留的图一定会是路径中的点挂着若干个路径以外的点,并且这些点可以任意互相连边,路径中不同点挂着的点集一定不能互相连边。但是直接枚举这条路......
  • 舵机驱动——STM32F407ZGT6探索者——HAL库
    舵机驱动——STM32F407ZGT6探索者——HAL库1、材料准备开发板:正点原子STM32F407ZGT6探索者舵机:SG90舵机线材分辨:褐色/红色/橘黄色——GND/VCC/PWM_signal与开发板接线:褐色/红色/橘黄色——GND/+5V/PF6(任选的PF6)2、知识准备2.1、舵......
  • Java面试题:链表-反转链表
    问题描述给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。示例输入:{1,2,3}返回值:{3,2,1}原题地址:https://www.nowcoder.com/practice/7......
  • 洛谷P5707 【深基2.例12】上学迟到(Python 3)
    题。审题:1.yyy要花十分钟垃圾分类!不要忘了在总分钟数上加102.如果时或分为个位数,则需要用0在前补位 思路:先把总共需要的分钟数算出来,然后求时和分。如果时大于8,那么再补上24,用来使时间符合格式。 关键点:1.补位:print('%02d'%m),具体看这篇2.注意当分钟数恰好为60倍数的......
  • 寻找两个链表相交节点方法(可以是有环链表)
    问题分析:两个链表相交可以分为两个大类,一是两个无环链表相交,二是两个有环链表相交。 无环相交如图:有环相交有两种情况,一种是先相交后成环,如图:另一种是交点有两个,是成环后的交点(入环节点不同) 方法1.判断链表是否有环,返回第一个入环节点。2.判断是否相交3.......