LeetCode-142.环形链表 II(相关话题:双指针)

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

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

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

示例 1:

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

示例 2:

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

示例 3:

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

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

Java代码:

public class Solution {
    /**
     * 1--2--3--4
     *    |_____|
     *
     * 初始时:slow、fast指向head
     * slow慢指针每次移动一步、fast快指针每次移动两步,相遇时,假设slow指针移动了x步,fast指针移动了2x步
     * slow和fast指针在节点4相遇
     *
     * 假设head到环的入口(即节点2)的长度为a,slow指针在环内走的长度为b,环的长度为c,
     * a+b = x
     * a+b+c = 2x
     * => c = x即环的长度
     * slow指针走了环的长度,需找到环的入口(即节点2),只需用一个工作指针p,从head出发,slow指针同时移动
     * slow与p相遇处,即为环的入口
     * (相遇时,p走了a步,slow走了x+a步,x为环的长度,因此p与slow会相遇)
     *
     */
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head, fast = head, p = head;
        while (null != fast && null != fast.next) {
            slow = slow.next;
            fast = fast.next.next;

            if (slow == fast)
                break;
        }
        if (null == fast || null == fast.next)
            return null;

        while (p != slow) {
            slow = slow.next;
            p = p.next;
        }

        return p;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_38823568/article/details/87855833
今日推荐