LeetCode 142:环形链表 II Linked List Cycle II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
Note: Do not modify the linked list.
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。

进阶: 你是否可以不用额外空间解决此题?
Follow-up: Can you solve it without using extra space?
解题思路:
和上一道题比只多了一步判断入环节点在哪。两种方法:
哈希表:
哈希表添加节点时只要发现节点已经存在了,证明就有环形链表。并且已存在的节点即为入环节点
双指针:
画了个图帮助理解:

一快一慢双指针开始从头结点遍历链表,快节点速度为2,慢节点速度为1:
相遇时:
慢节点走了:a+b
由于快指针速度是慢指针的2倍,快节点走了:2(a+b)
快慢节点相遇时快节点比慢节点刚好多走了一圈环形节点。快节点走了:(a+b)+(b+c)
列方程:2(a+b)=(a+b)+(b+c)
解得 a=c
也就是说:相遇节点到入环节点的长度和头节点到入环节点的长度相等
可以得出结论,如果此时让慢节点或快节点中的一个指向头节点,另一个留在相遇节点,然后速度都为1,继续遍历链表,双指针再次相遇时的节点刚好是入环节点。
注:为了理解方便,把长度 b 定为上半部分长度,实际上 b 应该为快慢节点相遇时慢节点绕过环形链表的总长度
哈希表解题:
Java:
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null) return null;//如果是空链表直接返回
Set<ListNode> nodeSet = new HashSet<>();//构造哈希表
while (head.next != null) {//链表下一个不为空
if (nodeSet.contains(head)) return head;//哈希表包含该节点则存在环形链表
nodeSet.add(head);//加入节点
head = head.next;//下移一位
}
return null;
}
}
Python:
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head is None:
return None
hashSet=set()#构造集合
while(head.next is not None):
if head in hashSet:#是否已存在
return head
hashSet.add(head)
head=head.next
return None
双指针解题:
Java:
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) {
return null;
}
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {//快指针及其下一位是否为null
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {//如果相同,存在环形链表
slow = head;//指向头节点
while (slow != fast) {//继续遍历,再次相遇时的节点即为入环节点
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
}
}
Python:
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head is None or head.next is None:
return None
slow, fast = head, head
while fast is not None and fast.next is not None:
slow, fast = slow.next, fast.next.next
if slow == fast:
slow = head
while slow != fast:
slow = slow.next
fast = fast.next
return slow
return None
欢迎关注公众号:爱写Bug(ID:iCodeBugs)

LeetCode 142:环形链表 II Linked List Cycle II的更多相关文章
- LeetCode 141. 环形链表(Linked List Cycle)
题目描述 给定一个链表,判断链表中是否有环. 进阶:你能否不使用额外空间解决此题? 解题思路 快慢指针,慢指针一次走一步,快指针一次走两步,若两者相遇则说明有环,快指针无路可走则说明无环. 代码 /* ...
- 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
环形链表II 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶:你是否可以不用额外空间解决此题? 链表头是X,环的第一个节点是Y,sl ...
- 【Leetcode】【Medium】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(Linker List Cycle II)
题目描述 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶: 你是否可以不用额外空间解决此题? 解题思路 分为三步: 首先判断是否存在 ...
- [Swift]LeetCode142. 环形链表 II | Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note ...
- LeetCode 142——环形链表II(JAVA)
给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...
- leetcode 142. 环形链表 II(c++)
给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...
随机推荐
- MySQL for OPS 12:锁处理
写在前面的话 在前面的内容中提到过,在以前的 MyISAM 中锁是表级锁,InnoDB 是行级锁.这个锁到底是啥样,怎么找出来,这一节就主要做这个. 定位锁的问题 上一节我们创建了一个 1000万数据 ...
- 前端之javascript1
js介绍和js引入页面 学习前端脚本语言javascript的基本概念.页面引入方式.获取页面元素及操作元素属性的技巧,学习函数的基本定义方法和使用方法. JavaScript介绍 JavaScrip ...
- sql server pivot
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[YearSalary]( [year] [int] NULL, ...
- c# 字符串中全角和半角字符互转
public class ConvertDBCAndSBC { /// <summary>半角转成全角 /// 半角空格32,全角空格12288 /// 其他字符半角33~126,其他字符 ...
- HTTP Error 500.35 - ANCM Multiple In-Process Applications in same Process
vs2019 win10 情况:报错 HTTP Error 500.35 - ANCM Multiple In-Process Applications in same Process 微软官方解 ...
- Python 内置函数补充匿名函数
Python3 匿名函数 定义一个函数与变量的定义非常相似,对于有名函数,必须通过变量名访问 def func(x,y,z=1): return x+y+z print(func(1,2,3)) 匿名 ...
- charAt()检测回文
package seday01; /** * char charAt(int index) 返回指定位置对应的字符 * @author xingsir */public class CharAtDem ...
- Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战
Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战 一.写在前面 在Java生鲜电商平台平台中相信不少朋友都在自己公司使用Spring Cloud框架来构建微服务架构,毕竟现在这 ...
- C#WinForm解决跨线程访问控件属性报错
方式一(在程序初始化构造函数中加一行代码): public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCal ...
- 移动端适配方案(rem+flex)
为什么用rem不用px? 主流:各大网站的移动版绝大多数都是用的rem. 移动端屏幕分辨率差别太大:最低适配的iPhone6,分辨率仅为750*1334.而现在市面上大多数手机,都达到了1080* ...