142#环形链表2

Posted yuzhenzero

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了142#环形链表2相关的知识,希望对你有一定的参考价值。

题目描述

142#环形链表

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

说明:不允许修改给定的链表。

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


分析

使用双指针可以解决该问题。

  • 链表没有环的判定可以参考第141题,环形链表

现在在链表有环的情况下分析。设一个快指针和一个慢指针,这两个指针的初始位置都在head,慢指针移动速度为1,快指针是它的两倍。

技术分享图片

如图,设从head到环形开始结点的距离是A,慢指针从环形开始结点走到相遇点走过的路程是B,环的长度是L(画图的时候漏掉了,图中没有标示出来)。于是有:

  • 对慢指针,从head走到meet的距离为A+B
  • 对快指针,从head走到meet的距离为2A+2B(因为快指针的速度是慢指针的两倍,而在相遇时它们走了相同的时间)
  • 相遇时,慢指针被快指针套了一圈,即快指针比慢指针多走一圈

根据以上分析我们可以列一个等式:A+B+L = 2A+2B,可以解得L = A + B。从这个结果可以看出,meetbegin的距离也是A。这意味着,如果我们分别放两个指针在headmeet,让它们以相同的速度前进,它们第一次相遇的地方就是我们要找的环形开始结点。

源码

/**
 * 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) {
        if (head == null)
            return null;
        ListNode fast = head;
        ListNode slow = head;
        
        while (fast != null && fast.next != null)
        {
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow)
            {
                slow = head;
                while (slow != fast)
                {
                    slow = slow.next;
                    fast = fast.next;
                }
                return slow;
            }
        }
        return null;
    }
}

以上是关于142#环形链表2的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode Java刷题笔记—142. 环形链表 II

141. 环形链表 142.环形链表

算法热门:环形链表II(LeetCode 142)

142. 环形链表 II

LeetCode 142. 环形链表 II(逻辑环链表快慢双指针)

LeetCode第142题—环形链表II—Python实现