【LeetCode题解】142_环形链表2(Linked-List-Cycle-II)
描述
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
说明:不允许修改给定的链表。
进阶:
你是否可以不用额外空间解决此题?
解法一:哈希表
思路
最直接的解法就是利用一个集合保存每次遍历的节点的引用。之后,从链表头开始遍历,每遍历一个节点,就判断该节点的引用是否在集合中,如果不在集合中,则将该节点的引用放入集合中;如果在集合中,则返回该节点的引用(环的入口)。当然,如果能遍历到链表尾部,此时链表无环,返回 null。
Java 实现
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
import java.util.Set;
import java.util.HashSet;
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode curr = head;
Set<ListNode> nodesSeen = new HashSet<>();
while (curr != null) {
if (nodesSeen.contains(curr)) {
return curr;
}
nodesSeen.add(curr);
curr = curr.next;
}
return curr;
}
}
Python 实现
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
curr = head
nodes_seen = set()
while curr:
if curr in nodes_seen:
return curr
nodes_seen.add(curr)
curr = curr.next
return curr
复杂度分析
- 时间复杂度:\(O(n)\)
- 空间复杂度:\(O(n)\)
解法二:双指针
思路
和 LeetCode 第 141 题一样,如果不想占用额外的空间的话,可以采用双指针的方式。
假设链表的起始节点为 A,环的入口节点为 B,两个指针(快慢指针)相交节点为 C,AB 两点之间的长度为 \(x\),BC 两点之间的长度为 \(y\),CB 两点之间的长度为 \(z\)。慢指针 slow 走过的长度为 \(x+y\),快指针 fast 为了“赶上”慢指针,应该走过的长度为 \(x + y + z + y\),同时,由于快指针的速度是慢指针的两倍,因此相同时间内,快指针走过的路程应该是慢指针(走过的路程)的两倍,即

\]
化简得,
\]
因此,如果此时有另外一个慢指针 slow2 从起始节点 A 出发,则两个慢指针会在节点 B (环的入口)相遇。
Java 实现
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
ListNode slow2 = head;
while (slow != slow2) {
slow = slow.next;
slow2 = slow2.next;
}
return slow;
}
}
return null;
}
}
// Runtime: 1 ms
// Your runtime beats 100.00 % of python submissions.
Python 实现
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
slow2 = head
while slow != slow2:
slow = slow.next
slow2 = slow2.next
return slow
return None
# Runtime: 44 ms
# Your runtime beats 99.73 % of python submissions.
复杂度分析
- 时间复杂度:\(O(n)\),其中 \(n\) 表示链表的长度。最坏的情况下(链表有环),需要迭代的次数为 \(x + y + z = n\) 次,因此时间复杂度为 \(O(n)\)
- 空间复杂度:\(O(1)\),只需要存储 3 个引用
【LeetCode题解】142_环形链表2(Linked-List-Cycle-II)的更多相关文章
- Leetcode 141题 环形链表(Linked List Cycle) Java语言求解
题目描述: 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中没有环. Map ...
- [LeetCode题解]142. 环形链表 II | 快慢指针
解题思路 本题是在141. 环形链表基础上的拓展,如果存在环,要找出环的入口. 如何判断是否存在环,我们知道通过快慢指针,如果相遇就表示有环.那么如何找到入口呢? 如下图所示的链表: 当 fast 与 ...
- LeetCode 141. 环形链表(Linked List Cycle)
题目描述 给定一个链表,判断链表中是否有环. 进阶:你能否不使用额外空间解决此题? 解题思路 快慢指针,慢指针一次走一步,快指针一次走两步,若两者相遇则说明有环,快指针无路可走则说明无环. 代码 /* ...
- [LeetCode题解]141. 环形链表 | 快慢指针
题目描述 给定一个链表,判断链表中是否有环. 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的 ...
- [LeetCode]题解(python):142-Linked List Cycle II
题目来源: https://leetcode.com/problems/linked-list-cycle-ii/ 题意分析: 给定一个链表,如果链表有环,返回环的起始位置,否则返回NULL.要求常量 ...
- 【链表】Linked List Cycle II
题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...
- LeetCode 142. 环形链表 II(Linked List Cycle II)
142. 环形链表 II 142. Linked List Cycle II 题目描述 给定一个链表,返回链表开始入环的第一个节点.如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整 ...
- [LeetCode] Linked List Cycle II 单链表中的环之二
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...
- [LeetCode] 142. Linked List Cycle II 单链表中的环之二
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To r ...
- [算法][LeetCode]Linked List Cycle & Linked List Cycle II——单链表中的环
题目要求 Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up: Can you so ...
随机推荐
- Android-系统解析AndroidManifest
在上一篇博客,Android-XML格式描述,介绍来XML在Android中的格式: Android-系统解析AndroidManifest,是分析Android系统是如何去解析AndroidMani ...
- Win10系统下编译OSG3.4
环境说明 1.Win10专业版.64位: 2.VS2012旗舰版:QT5.2.0: 3.cmake-3.9.0.64位: 资源准备 1.OSG3.4源码包 http://trac.opensceneg ...
- 在AbpZero中hangfire后台作业的使用——hangfire的调度
在abpzero框架中,hangfiire通过依赖注入来进行接口的调用 hangfire的事件处理分为以下几种: 1.基于队列的任务处理(Fire-and-forget jobs) var jobId ...
- ASP.NET MVC 富文本Ueditor编辑 后台传值前端乱码解决方案
只是将当前内容String当成Html插入,我想是跟数据类型转换差不多 //把内容赋值给ueditor var ue = UE.getEditor('editor');//实例化 ue.ready(f ...
- 使用vs code开发纸壳CMS并启用Razor智能提示
关于纸壳CMS 纸壳CMS是一个开源免费的,可视化设计,在线编辑的内容管理系统.基于ASP .Net Core开发,插件式设计: 下载代码 GitHub:https://github.com/Seri ...
- L-BFGS算法介绍
可以看出,拟牛顿法每次迭代只需要根据前次迭代的即可以计算出,不需要求出Hesse矩阵的逆. 2.4 L-BFGS(limited-memory BFGS) BFGS算法中每次迭代计算需要前次迭代得到的 ...
- 隐藏导航栏,偏移20PX
1:让ViewController在NavigationBar下面开始布局. automaticallyAdjustsScrollViewInsets作用 当Controller上存在唯一一个UISc ...
- 欢迎使用CSDN-markdown编辑器a
这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题,有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一 ...
- 安装Apache时端口号被占用解决方案
有些朋友的电脑在安装Apache是会遇到端口冲突的问题.以下是一种解决方案 1.打开控制面板的管理工具 2.打开IIS 3.观察网站下的端口号 4.点击绑定 5.更改端口号 6.重新启动即可
- 项目实体类使用@Data注解,但是项目业务类中使用getA(),setA()方法报错,eclipse中配置lombok
@Data注解来源与Lombok,可以减少代码中大量的set get方法,大量减少冗余代码,但是今天部署项目时候,发现实体类使用@Data注解,但是项目业务类中使用getA(),setA()方法报错. ...