LeetCode 142. Linked List Cycle II(C++版)

来源:互联网 发布:手机音乐合成剪辑软件 编辑:程序博客网 时间:2024/06/12 06:56

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?

思路:

在链表头和相遇点分别设一个指针,每次各走一步,两个指针的第一个相遇点即环入口点。

原理:

当fast与slow相遇时,slow还没有走完链表,而fast已经在链表的环内循环了n圈(n为正整数,n >= 1)。假设slow走了s步,那么fast则走了2

s步,设环长为r,则应满足:2s - s = nr 。那么 s = nr。

设整个链表长度为l,环的入口处与相遇点的距离为x,起点到环入口点的距离为a,那么:

a + x = s = nr,

a + x = (n - 1) r + r = (n - 1)r + l - a

a = (n - 1)r + (l - a - x)

l - a - x为相遇点到交叉点的距离。取n = 1 时,即fast只比slow多走了一圈,正好fast和slow第一次相遇时,a = l - a - r, 也即是从链表起点到环的入口点的距离刚好等于从相遇点走到环的入口点的距离。所以可以使两个指针分别从链表起点p和fast与slow的相遇点q开始走,p和q相遇的点即环的入口点。

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


0 0