Leetcode142 - Linked List Cycle II(链表)

来源:互联网 发布:网贷数据分析 编辑:程序博客网 时间:2024/05/21 15:00

题意

给定一个链表,判断这个链表内是否存在环,并且求这个环的起点。

思路

如图所示:
这里写图片描述

我们再假设圆的周长为r,我们需要求的是a。
于是,我们设置两个指针slow和fast,slow每次走一步,fast每次走两步,并且两个都走了t时间,于是:

slow:t=a+b ==>为什么不是t==a+b+mr:因为slow一旦进入环,不会跑超过一圈就会和fast相遇。

fast:2t=a+b+nr

我们可以解得:

nr=a+b

上面式子的意思即:我们从相遇的点C出发,再走a步,能够走到环的起点!即:我们的slow和fast相遇在C点了, 这时候,我们把slow放回起点A,fast放在C点,两个同时开始走且步速均为1,那么我们相遇的点就是B点!

Follow up

  1. 求环的长度

    首先,我们不能从起点到C点的相遇来确定环长,因为之间相差的是环长的若干倍,并且倍数还不能确定。

    但是,当我们第一次在C点相遇后,之后,fast继续走两步,slow继续走一步。再次相遇时,刚好相差一圈。就追及问题。

  2. 将有环链表变成单链表

    我们找到B点之后,记录下B点的位置,然后绕着环走,再次走到B点时结束。

代码

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