打败算法 —— 环形链表 II
本文参考
出自LeetCode上的题库 —— 环形链表II,哈希表和快慢指针两种解法都需要O(n)的时间,但快慢指针仅占用O(1)的空间
https://leetcode-cn.com/problems/linked-list-cycle-ii/
环形链表问题
给定一个链表的头节点 head,返回链表开始入环的第一个节点(不允许修改链表)
如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环
示例1:
输入:head = [3,2,0,-4]
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点
示例2:
输入:head = [1,2]
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点
示例3:
输入:head = [1]
输出:返回 null
解释:链表中没有环
解题思路
首先是特殊情况,当没有节点,或有节点却不存在环的情况下,容易通过节点或节点的next指针是否空进行判断
当节点间存在环路时,第一种直观的解法,使用一个指针沿着链路走下去,每走一步将节点存入set集合,当碰到重复出现的节点时,该节点就是环路的入口;
第二种解法需要应用两遍双指针,可能刚接触这道题时已经想到了快慢指针,但是我们无法保证快指针和慢指针相遇的位置一定是环路的入口,以至于否定了这种解法。此处需要一定的数学分析,在快慢指针相遇的位置引入第三个指针:
令总节点数为$n$,头节点为$head$,环路的入口节点为$entry$,环路中快慢指针相遇的节点位置为$meet$,定义距离$a=Distance(head,entry)$,距离$b=Distance(entry,meet)$,距离$c=Distance(meet,entry)$,满足$n=a+b+c$
当快慢指针相遇时,快指针走过的路径长度为$d_{fast}=a+n(b+c)+b$,慢指针走过的路径长度为$d_{slow}=a+b$,我们预先设置快指针每次走两步,慢指针每次走一步,则$d_{fast}=2d_{slow}=a+n(b+c)=2(a+b)$,化简得$a=c+(n-1)(b+c)$,$a$的长度是$c$的长度加上$(n-1)$圈的环路长度
因此,我们引入第三个指针ptr,慢指针从相遇位置开始移动,ptr从头指针开始移动,由公式$a=c+(n-1)(b+c)$可知,二者相遇的位置即为环路的路口
哈希表解法
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def detect_cycle_1(self, head: ListNode) -> ListNode:
if head is None or head.next is None:
return None
node_set = set()
curr_node = head
while curr_node not in node_set:
node_set.add(curr_node)
if curr_node.next is None:
return None
else:
curr_node = curr_node.next
return curr_node
快慢指针解法
def detect_cycle_2(self, head: ListNode) -> ListNode:
slow = fast = head
while fast is not None:
# 慢指针每次走一步
slow = slow.next
if fast.next is None:
return None
# 快指针每次走两步
fast = fast.next.next
# 快慢指针相遇
if fast == slow:
ptr = head
# 建立新的双指针走法
while ptr != slow:
ptr = ptr.next
slow = slow.next
return ptr
return None
打败算法 —— 环形链表 II的更多相关文章
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II
[算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...
- LeetCode142 环形链表 II
给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶:你是否可以不用额外空间解决此题? //章节 - 链表 //二.双指针技巧 //2.环 ...
- Leetcode 142.环形链表II
环形链表II 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶:你是否可以不用额外空间解决此题? 链表头是X,环的第一个节点是Y,sl ...
- Leetcode.142-Linked-list-cycle-ii(环形链表II)
环形链表II 思路 https://www.cnblogs.com/springfor/p/3862125.html https://blog.csdn.net/u010292561/article/ ...
- LeetCode 142. 环形链表 II(Linked List Cycle II)
142. 环形链表 II 142. Linked List Cycle II 题目描述 给定一个链表,返回链表开始入环的第一个节点.如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整 ...
- Java实现 LeetCode 142 环形链表 II(二)
142. 环形链表 II 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始 ...
- 【LeetCode】142. 环形链表 II
142. 环形链表 II 知识点:链表:set:快慢指针 题目描述 给定一个链表,判断链表中是否有环. 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表 ...
- 代码随想录第四天| 24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点 、160.链表相交、142.环形链表II
今天链表致死量 第一题 public static class ListNode { int val; ListNode next; ListNode() {} ListNode(int val) { ...
- LeetCode 142:环形链表 II Linked List Cycle II
给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...
随机推荐
- Ecma335、CLR、CLI、CTS、 IL、.net 以及他们之间的关系
以上是个人对他们直接关系的理解:图片是原创 CLI 通用语言基础架构(Common Language Infrastructure), CLI是一个开放型的技术规范,它定义了一个语言无关的跨体系结构的 ...
- 从零开始,开发一个 Web Office 套件(6):光标 & Click 事件
<从零开始, 开发一个 Web Office 套件>系列博客目录 这是一个系列博客,最终目的是要做一个基于 HTML Canvas 的.类似于微软 Office 的 Web Office ...
- Oracle账户被锁:the account is locked
转至:https://blog.csdn.net/weixin_37615080/article/details/80400239?utm_medium=distribute.pc_relevant_ ...
- Python3对接华三CAS平台Api获取虚拟机监控信息-渐入佳境
--时间:2021年2月3日 --作者:飞翔的小胖猪 说明 使用python对接华三CAS虚拟化平台,通过厂商提供的api接口获取每个集群下所有虚拟机的监控信息,并保存数据在本地的mariadb数据库 ...
- 教程1--安装Git软件
在https://git-scm.com/下载git for windows,双击安装即可. (1)单击Next (2)选择安装目录 (3)勾选创建桌面快捷方式.Git Bash.Git GUi.已经 ...
- omnet++:cMessage、cSimpleModule、cGate
cMessage Message可以被调度(self-message).取消.从一个Gate发送出去.直接发给另一个module:所有以上,都是通过cSimpleModule来实现的. Message ...
- 普通web整合quartz跑定时任务
一.场景(什么时候用到定时任务) 文件跑批,定时处理数据,和业务解耦的场景 二.目前都有哪些工具可以定时处理数据 1.jdk的timertask:数据量小的情况下,单线程的 2.kettle:比较适合 ...
- JAVA String、StringBuilder、和StringBuffer的区别,及如何使用
目录 String类 一.String类的理解和创建对象 二.String类创建的方式 两种创建String对象的区别 测试题 三.String常用方法 四.StringBuffer类 1.Strin ...
- c# 通过HttpListener创建HTTP服务
在c#中可以利用HttpListener来自定义创建HTTP服务,通过http协议进行服务端与多个客户端之间的信息传递,并且可以做成windows系统服务,而不用寄宿在IIS上.以下为一个demo,分 ...
- 2022年官网下安装RedisDesktopManager最全版与官网查阅方法
目录 安装部署RedisDesktopManager 一.下载安装 1.浏览器输入网址:https://github.com/ ,输入搜索条件,找到如图,双击 2.滑动浏览器找到如图位置,双击 3.滑 ...