zoukankan      html  css  js  c++  java
  • 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)

    爱写bug.png

  • 相关阅读:
    centos7grub2 引导win10
    必测的支付漏洞(一)——使用fiddler篡改支付金额
    使用Fiddler进行IOS APP的HTTP抓包
    Fiddler实现手机抓包——小白入门
    信息收集工具recon-ng详细使用教程
    Chrome浏览器扩展开发系列之一:初识Google Chrome扩展
    Dear Project Manager, I Hate You
    敏捷中的沟通与故事点
    项目经理与敏捷开发
    C#中使用反射获取结构体实例
  • 原文地址:https://www.cnblogs.com/zhangzhe532/p/11200194.html
Copyright © 2011-2022 走看看