leetcode Linked List Circle

来源:互联网 发布:面试php基础知识 编辑:程序博客网 时间:2024/06/18 17:34

首先要判断一个链表是否是循环的,只要设置一个fast指针和slow指针,每次fast指针走两步,slow指针走一步,如果fast等于NULL证明不存在circle,如果fast==slow,则证明存在circle 然后假如链表存在循环要找出链表的入口的话,需要一点计算技巧,设起点到循环入口的距离为L,循环的长度为R。两个指针第一次相遇的位置为 x%R,x为slow指针在循环圈中走的距离,这时候有(2*(L+x)-L)%R=x%R,整理得有(L+x)%R==0 所以也就是说slow指针只需要在移动L步就可以到达循环的入口处,而这个时候我们需要将fast指针移到开头走L步,便有fast等于slow。所以我们只需要将fast移到开头后,然后每走一步判断fast和slow是否相等,如果相等,返回fast指针即可。注意的是L可能为0,所以我们需要将fast和slow先判断下,然后再进行各移动一步的操作。

代码如下

struct ListNode {      int val;      ListNode *next;      ListNode(int x) : val(x), next(NULL) {}}; class Solution {public:    bool hasCycle(ListNode *head)     {        if(head == NULL)            return false;        ListNode *fast = head;         ListNode *slow = head;        while (true)        {            fast = fast->next;            if(fast == NULL)                return false;            if(fast == slow)                return true;            fast = fast->next;            if(fast == NULL)                return false;            if(fast == slow)                return true;            slow = slow->next;        }    }    ListNode *detectCycle(ListNode *head)    {        if(head == NULL)            return NULL;        ListNode *fast = head;        ListNode *slow = head;        while(true)        {            fast = fast->next;            if(fast == NULL)                return NULL;            fast = fast->next;            if(fast == NULL)                return NULL;            slow = slow->next;            if(fast == slow)            {                fast = head;                break;            }        }        while(true)        {            if(fast == slow)                return fast;            fast = fast->next;            slow = slow->next;        }    }};


0 0
原创粉丝点击