美文网首页
Leetcode142环形链表Ⅱ

Leetcode142环形链表Ⅱ

作者: answerLDA | 来源:发表于2019-10-22 13:48 被阅读0次

题目

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

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

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

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

image.png

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

image.png

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

image.png

分析

题解转至于:https://leetcode.wang/

原理也很好理解,想象一下圆形跑道,两个人跑步,如果一个人跑的快,一个人跑的慢,那么不管两个人从哪个位置出发,跑的过程中两人一定会相遇。

所以这里我们用两个指针 fast 和 slow。fast 每次走两步,slow 每次走一步,如果 fast 到达了 null 就说明没有环。如果 fast 和 slow 相遇了就说明有环。

但是这道题,我们需要找到入口点,而快慢指针相遇的点可能并不是入口点,而是环中的某一个点,所以需要一些数学上的推导,参考了 这里 。

如下图,我们明确几个位置。


image.png

从 head 到入口点的距离设为 x,入口点到相遇点的距离设为 y,环的的长度设为 n。

假设 slow 指针走过的距离为 t,那么 fast 指针走过的一定是 slow 指针的 2 倍,也就是 2t。

slow 指针从 head 出发走了 x 的距离到达入口点,然后可能走了 k1 圈,然后再次回到入口点,再走了 y 的距离到达相遇点和 fast 指针相遇。

t = x + k1 * n + y

fast 指针同理,fast 指针从 head 出发走了 x 的距离到达入口点,然后可能走了 k2 圈,然后再次回到入口点,再走了 y 的距离到达相遇点和 slow 指针相遇。

2t = x + k2 * n + y

上边两个等式做一个差,可以得到

t = (k2 - k1) * n

设 k = k2 - k1 ,那么 t = k * n。

把 t = k * n 代入到第一个式子 t = x + k1 * n + y 中。

k * n = x + k1 * n + y

移项,x = (k - k1) * n - y

取出一个 n 和 y 结合,x = (k - k1 - 1) * n + (n - y)

左边的含义就是从 head 到达入口点。

右边的含义, n - y 就是从相遇点到入口点的距离,(k - k1 - 1) * n 就是转 (k - k1 - 1) 圈。

左边右边的含义结合起来就是,从相遇点走到入口点,然后转 (k - k1 - 1) 圈后再次回到入口点的这段时间,刚好就等于从 head 走向入口点的时间。

所以代码的话,我们只需要 meet 指针从相遇点出发的同时,让 head 指针也出发, head 指针和 meet 指针相遇的位置就是入口点了。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow = head,*fast = head,*meet;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
            //到达相遇点
            if (fast == slow) {
                meet = fast;
                while (head != meet) {
                    head = head->next;
                    meet = meet->next;
                }
                return head;
            }
        }
        return NULL;
    }
};

相关文章

  • Leetcode142环形链表Ⅱ

    题目 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们...

  • leetcode142 环形链表2 形象解释

    给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 设快指针一次跳两下,慢指针一次跳一...

  • 实现单向-双向环形链表

    单向环形链表 双向环形链表

  • 双指针

    一、双指针总结 1.1题目 快慢指针(主要解决链表中的问题) 141.环形链表 142.环形链表 II 876.链...

  • 02-14:leetcode重刷8之哈希与数组

    链表: 判断链表是否环形、是否回文 1、是否链表 #Definitionforsingly-linkedlist....

  • Tourist with Data Structure Seco

    链表 读题要仔细,只看题干,容易死的很惨。 设计链表 环形链表 一般环形链表使用快慢指针方式去做,快慢指针算法。参...

  • 算法(Algorithms)第4版 练习 1.3.29

    题目 使用环形链表实现队列(FIFO),环形链表也是链表,只是没有任何一个节点的链接是空的,且只有链表非空则 la...

  • 判断一个链表是否为环形链表

    判断一个链表是否为环形链表 思路:通过检测一个节点此前是否已经被访问过来判断链表是否为环形链表。 算法: 我们遍历...

  • 单项环形链表介绍和约瑟夫问题

    单项环形链表介绍和约瑟夫问题 1.单项环形链表图解 2.Josephu(约瑟夫)问题 Josephu 问题为:设...

  • 链表—环形链表

    给定一个链表,判断链表中是否有环。 分析 由于每一个父亲只有可能有一个孩子,故这里的环实际上是指list中某一个节...

网友评论

      本文标题:Leetcode142环形链表Ⅱ

      本文链接:https://www.haomeiwen.com/subject/oodqvctx.html