【刷题】142. 环形链表 II

news2025/1/15 12:55:41

142. 环形链表 II

  • 一、题目描述
  • 二、示例
  • 三、实现
    • 3.1 方法1
    • 3.2 方法2


142. 环形链表 II

一、题目描述

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

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

不允许修改 链表。

二、示例

示例1:

在这里插入图片描述

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

示例2:

在这里插入图片描述

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

示例3:

在这里插入图片描述

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

三、实现

3.1 方法1

假设:

链表头到环入口点距离 = L
环入口点到相遇点距离 = X
环的长度 = C

slow走的路程: L + X L + X L+X

fast走的路程: L + n ∗ C + X L + n*C + X L+nC+X

由于fast速度是slow的两倍,则有等式: 2 ∗ ( L + X ) = L + n ∗ C + X 2*(L+X) = L + n * C + X 2(L+X)=L+nC+X
解得: L = n ∗ C − X = ( n − 1 ) ∗ C + C − X L = n*C - X = (n-1)*C + C-X L=nCX=(n1)C+CX

因此从链表头到环入口点距离( L = ( n − 1 ) ∗ C + C − X L = (n-1)*C + C-X L=(n1)C+CX)和从相遇点到环入口点距离( C − X C-X CX)相同,只是差了 ( n − 1 ) ∗ C (n-1)*C (n1)C 也就是 n − 1 n-1 n1 个环长。

由上可知,我们使用两个指针,一个指针从相遇点走,一个指针从链表头开始走,他们必定会在入口点相遇。

struct ListNode* detectCycle(struct ListNode* head) {
	struct ListNode* slow = head, * fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;

		// 带环 在环中相遇
		if (slow == fast)
		{
			struct ListNode* meet = slow;
			// 求入口点
			while (head != meet)
			{
				head = head->next;
				meet = meet->next;
			}

			return meet;
		}
	}

	return NULL;
}

3.2 方法2

快慢指针在环中相遇,把相遇点变成原链表的尾结点,相遇点的下一个结点变为新链表的头结点,这样求环的入口点问题,就变成了找两个链表的交点问题了。

但这会时间超时:参考代码 【求两个链表的交点-getIntersectionNode】

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
	struct ListNode* tailA = headA;
	struct ListNode* tailB = headB;

	// 1.判断是否相交 通过查看两个链表的尾结点是否相同
	int lenA = 1, lenB = 1;
	while (tailA->next)
	{
		tailA = tailA->next;
		++lenA;
	}

	while (tailB->next)
	{
		tailB = tailB->next;
		++lenB;
	}

	if (tailA != tailB)
	{
		return NULL;
	}

	// 2.找交点,让长的链表先走 差距 步
	int gap = abs(lenA - lenB);
	struct ListNode* longList = headA;
	struct ListNode* shortList = headB;
	if (lenA < lenB)
	{
		longList = headB;
		shortList = headA;
	}

	while (gap--)
	{
		longList = longList->next;
	}

	while (longList != shortList)
	{
		longList = longList->next;
		shortList = shortList->next;
	}

	return longList;
}

struct ListNode* detectCycle(struct ListNode* head) {
	struct ListNode* slow = head, * fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;

		// 带环 在环中相遇
		if (slow == fast)
		{
			struct ListNode* meet = slow;
			
			return getIntersectionNode(head, meet->next);
		}
	}

	return NULL;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501549.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端学习 - 淼哥学Vue

如何判断数据是否受Vue管理&#xff0c;数据&#xff08;对象&#xff0c;数组&#xff0c;字符串等&#xff09;能否响应式更新&#xff1f; 即查看数据是否有对应get/set方法&#xff0c;数组没有对应get/set方法&#xff0c;故操作数组要通过其封装好的变更方法 变更方法 …

js高级知识汇总一

目录 1.怎么理解闭包&#xff1f; 2.闭包的作用&#xff1f; 3.闭包可能引起的问题&#xff1f; 4.变量提升 5.函数动态参数 6.剩余参数 ...&#xff08;实际开发中提倡使用&#xff09; 7.展开运算符 8.箭头函数 9.解构赋值&#xff08;数组、对象&#xff09; 10 创…

一文总结动态规划

动态规划 一、背包问题1 问题定义2 问题分类3 解题模板01背包最值问题剩余背包问题 4 例题分析LeetCode1049.最后一块石头的重量II 二、区间动态规划1 解题模板2 例题分析牛客.石子合并 总结与分析 一、背包问题 1 问题定义 如何确定一个题目是否可以用背包问题解决 背包问题…

给儿童使用护眼台灯怎么样选择更好?专家建议孩子买台灯

随着娃越长越大&#xff0c;虽然还在读幼儿园&#xff0c;但平时免不了要写写画画&#xff0c;之前一直在这个桌子上&#xff0c;台灯是一个赠送的LED货色&#xff0c;那个频闪啊&#xff0c;于是趁着当地商场活动先入了张学习桌椅&#xff0c;至于台灯嘛当然要选个好的了&…

21财经专访徐亚波博士:AI恒纪元时代,数说故事踏浪新征途

21世纪经济报道【创业投资】栏目&#xff0c;一直致力于寻找中国最有生命力和创造力的快速成长公司&#xff0c;探秘其背后的新兴资本推动力。为此&#xff0c;数说故事创始人兼CEO徐亚波博士接受了21世纪经济报道的专访。 近年来&#xff0c;大数据产业已经成为推动数字经济发…

【C语言】都玩过三子棋游戏把,但你知道怎么用C语言实现三子棋游戏吗?让我来手把手教你。

三子棋游戏 1.前言2.功能分析2.1主函数设计及菜单设计2.2打印棋盘与棋盘初始化2.3玩家下棋2.4电脑下棋2.5判断输赢 3.game.h头文件展示4.text.c源文件文件展示5.game.c源文件文件展示 所属专栏&#xff1a;C语言 博主首页&#xff1a;初阳785 代码托管&#xff1a;chuyang785 感…

Android 开发中高阶函数的 10 个实例

Android 开发中高阶函数的 10 个实例 Kotlin 是一种现代编程语言&#xff0c;由于其表现力、简洁性和多功能性而变得越来越流行。它的关键特性之一是支持高阶函数&#xff0c;这使您可以编写更简洁、更灵活的代码。高阶函数是一种将一个或多个函数作为参数或返回一个函数作为结…

python+java+nodejs基于vue的企业人事工资管理系统

根据系统功能需求分析&#xff0c;对系统功能的进行设计和分解。功能分解的过程就是一个由抽象到具体的过程。 作为人事数据库系统&#xff0c;其主要实现的功能应包括以下几个模块&#xff1a; 1.登录模块 登录模块是由管理员、员工2种不同身份进行登录。 2.系统管理模块 用户…

工具抓包Charles配置HTTPS步骤

charles抓取HTTPS设置&#xff0c;详细踩坑版 写这篇文章的背景就是&#xff0c;每次我在一台新电脑上用charles抓包时&#xff0c;总是因为各种原因无法抓到https请求&#xff0c;每个百度出来的回答又不是那么详细&#xff0c;需要通过几篇回答才能解决过程中的各种问题&…

C++程序员的职业前景怎么样?来谈谈我自己的想法

我之前提到了程序员在二线城市的大概待遇。今天&#xff0c;我要说一下普通程序员的职业前景。因为最初阶段的工资可能比较高&#xff0c;但如果没有可持续性&#xff0c;这就不是一个特别好的工作。 从我自身的经验来看&#xff0c;我们公司的程序员主要有两条路线。一条是纯…

【存储数据恢复】NetApp存储WAFL文件系统数据恢复案例

存储数据恢复环境&#xff1a; NetApp存储设备&#xff0c;WAFL文件系统&#xff0c;底层是由多块硬盘组建的raid磁盘阵列。 存储故障&#xff1a; 工作人员误操作导致NetApp存储内部分重要数据被删除。 存储数据恢复过程&#xff1a; 1、将存储设备的所有磁盘编号后取出&…

软考A计划-常用公式复习

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

使用Nginx做反向代理

使用Nginx做反向代理 文章目录 使用Nginx做反向代理代理HTTP请求代理HTTPS请求举个大栗子 代理HTTP请求 按照以下步骤使用Nginx做反向代理&#xff1a; 编辑 Nginx 的配置文件。默认情况下&#xff0c;Nginx 的配置文件位于 /etc/nginx/nginx.conf。 sudo nano /etc/nginx/ngi…

1703_LibreOffice常用功能使用体验

全部学习汇总&#xff1a; GreyZhang/windows_skills: some skills when using windows system. (github.com) 首先需要说明的是我不是一个重度Office用户&#xff0c;甚至算不上一个重度的Office用户。我使用的Office软件最多的功能就是文档编辑&#xff0c;绝大多数时候还是文…

【什么是苹果推信?什么是苹果推?】通过苹果手机Imessage进行信息推送的方式;

如今不少人都在利用苹果手机&#xff0c;重要是装备高端&#xff0c;很少呈现卡机的征象&#xff0c;并且星移斗换快&#xff0c;紧跟互联网期间成长的脚步。苹果手机是火了&#xff0c;谁又能想到另有比它更火的事变出现呢&#xff0c;便是苹果推信。苹果推信主要上风是推信群…

晋商银行“沧海”数据资产管理系统

案例名称 晋商银行“沧海”数据资产管理系统 案例简介 晋商银行“沧海”数据资产管理系统&#xff0c;取自“海纳百川、沧海一粟”之意&#xff0c;即数据如茫茫大海&#xff0c;其价值不可估量。该系统贯穿数据的全生命周期&#xff0c;包括数据多维度描述、数据…

期末复习自用--python

前言 python的优点&#xff1a; 简洁&#xff0c;语法优美&#xff0c;简单易学&#xff0c;开源&#xff0c;可移植性好&#xff0c;拓展性好&#xff0c;类库丰富&#xff0c;通用灵活&#xff0c;模式多样&#xff0c;良好的中文支持。 python的缺点&#xff1a; 执行效率不…

1.信息的表示和处理

基础 进制转换 字数据大小 寻址和字节顺序&#xff08;大小端&#xff09; 01 23 45 67 大端法&#xff1a;最高有效字节&#xff08;01&#xff09;在最前面&#xff08;相当于正序&#xff09; 小端法&#xff1a;最低有效字节&#xff08;67&#xff09;在最前面&#xff0…

Ceph入门到精通-CrushMap算法概述

下面是伪代码object到osd的伪代码 locator =object_name obj_hash =hash(locator) pg =obj_hash %num_pg OSDs_for_pg =crush(pg) # returns a list of OSDs primary =osds_for_pg[0] replicas =osds_for_pg[1:] defcrush(pg): all_osds=[osd.0,osd.1,osd.2,...] resu…

【Linux内核解析-linux-5.14.10-内核源码注释】内核常用链表宏解释

1、list_for_each_entry_safe 这段代码是一个宏定义&#xff0c;用于遍历一个链表中所有的元素&#xff0c;并且在遍历过程中可以安全地删除元素。具体来说&#xff0c;这个宏定义的功能是&#xff1a; 遍历链表中所有的元素&#xff0c;从头节点开始&#xff0c;直到尾节点结束…