142. Linked List Cycle II(环形链表II)

题目描述

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

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

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

示例 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
解释:链表中没有环。

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

方法思路

解题思路:分两个步骤,首先通过快慢指针的方法判断链表是否有环。
接下来如果有环,则寻找入环的第一个节点。具体的方法为,首先假定链表起点到入环的第一个节点A的长度为x1【未知】,到快慢指针相遇的节点B的长度为(x1 + x2)【这个长度是已知的】。现在我们想知道x1的值,注意到快指针始终是慢指针走过长度的2倍,所以慢指针从B继续走(x1 + x2)又能回到B点,如果只走x1个长度就能回到节点A。但是x1的值是不知道的,解决思路是曲线救国,注意到起点到A的长度是x1,那么可以用一个从起点开始的新指针p和从节点B开始的慢指针同步走,相遇的地方必然是入环的第一个节点A。 文字有点绕,画个图就一目了然了

在这里插入图片描述

public class Solution {
    //Runtime: 0 ms, faster than 100.00%
    public ListNode detectCycle(ListNode head) {
        if(head == null)
            return head;
        ListNode slow = head, fast = head, p = head;
        boolean isCycle = false;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if(fast == slow){
                isCycle = true;
                break;
            }
        }
        if(isCycle){
            while(p != slow){
                p = p.next;
                slow = slow.next;
            }
            return p;
        }else
            return null;
    }
}

猜你喜欢

转载自blog.csdn.net/IPOC_BUPT/article/details/88168174
今日推荐