专栏首页爱写BugLeetCode 142:环形链表 II Linked List Cycle II

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 posis -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
解释:链表中有一个环,其尾部连接到第二个节点。

img

示例 2:

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

img

示例 3:

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

img

进阶: 你是否可以不用额外空间解决此题?

Follow-up: Can you solve it without using extra space?

解题思路:

和上一道题比只多了一步判断入环节点在哪。两种方法:

哈希表:

哈希表添加节点时只要发现节点已经存在了,证明就有环形链表。并且已存在的节点即为入环节点

双指针:

画了个图帮助理解:

爱写bug

一快一慢双指针开始从头结点遍历链表,快节点速度为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(iCodeBugs),作者:爱写bug

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • LeetCode 142:环形链表 II Linked List Cycle II

    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

    爱写bug
  • LeetCode 328:奇偶链表 Odd Even Linked List

    给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

    爱写bug
  • LeetCode 328:奇偶链表 Odd Even Linked List

    给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

    爱写bug
  • LeetCode 142:环形链表 II Linked List Cycle II

    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

    爱写bug
  • Day15:反转链表

    背景知识介绍   在做本题之前首先介绍一下链表的基本知识。在维基百科中,链表 是这样定义的:链表(Linked list)是一种常见的基础数据结构,是一种线...

    stefan666
  • LeetCode:移除重复节点-java实现

    整体思路:创建一个HashSet实例,从头节点开始遍历所有节点,遍历过程中如果HashSet中包括该节点的值,则判断下一个节点的值,否则将该节点的值添加到Has...

    一点博客
  • 链表高频题

    总结:所有链表题目都做过而且都Accept了,不排除有些是抄的。。leet, leet-cn

    王脸小
  • 数据结构基础之掌握5个常见的链表操作

    最近在重新梳理学算法的知识,本文为链表常见操作复习的总结文章,会讲解常见的链表题目实现思路及附上答案,这些题目在leetcode上对应的题号也有给出,好好学习算...

    winty
  • C# devExpress GridControl 行中行 子行 多级行

    乔达摩@嘿
  • python实现字典多层嵌套

    dict.setdefault(key,default=None) 如果键不存在于字典中,将会添加新的键,并将值设置为默认值;如果字典中包含该给定的键...

    py3study

扫码关注云+社区

领取腾讯云代金券