摘要:如果链表无环,则返回。说明不允许修改给定的链表。示例输入输出解释链表中有一个环,其尾部连接到第一个节点。两种方法哈希表哈希表添加节点时只要发现节点已经存在了,证明就有环形链表。
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 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;//如果是空链表直接返回 SetnodeSet = 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)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/75416.html
摘要:如果链表无环,则返回。说明不允许修改给定的链表。示例输入输出解释链表中有一个环,其尾部连接到第一个节点。两种方法哈希表哈希表添加节点时只要发现节点已经存在了,证明就有环形链表。 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该...
摘要:说明不允许修改给定的链表。算法思路题目要求返回单链表中存在循环链表的位置。首先,先判断该单链表是否存在循环链表用两个快慢指针分别指向链表的头部,每次移动两步,每次移动一步,移动的步数是的两倍。 Time:2019/4/8Title: Linked List Cycle IIDifficulty: mediumAuthor:小鹿 题目:Linked List Cycle II Giv...
摘要:题目要求这道题目要求判断一个链表中是否有环,如果有环,就返回环中的第一个节点。如果有环,就会重复遇到这个指向的节点。则该链表有环,且该节点就是环的起始节点。但是这个方法会毁坏原来链表的数据结构。 题目要求 Given a linked list, return the node where the cycle begins. If there is no cycle, return n...
摘要:微信公众号记录截图记录截图目前关于这块算法与数据结构的安排前。已攻略返回目录目前已攻略篇文章。会根据题解以及留言内容,进行补充,并添加上提供题解的小伙伴的昵称和地址。本许可协议授权之外的使用权限可以从处获得。 Create by jsliang on 2019-07-15 11:54:45 Recently revised in 2019-07-15 15:25:25 一 目录 不...
阅读 2302·2021-11-24 10:26
阅读 2546·2021-11-16 11:44
阅读 1682·2021-09-22 15:26
阅读 3531·2021-09-10 11:11
阅读 3159·2021-09-07 10:25
阅读 3586·2021-09-01 10:41
阅读 988·2021-08-27 13:11
阅读 3480·2021-08-16 11:02