链表中环的入口结点

时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路:

设置快慢指针都从链表头出发,快指针每次走两步,慢指针每次走一步,假如有环,一定可以相遇于环中某点(结论1)。接着让两个指针分别从相遇点和链表头出发,两者都改为每次走一步,最终相遇于环入口(结论2)。对上述两个结论,以下进行了证明:
两个结论:
1.设置快慢指针,假如有环,最终他们必相遇。
2.两个指针分别从链表头和相遇点继续出发,每次走一步,最终一定相遇于环入口。

证明结论1:设置快慢指针fast和low,fast每次走两步,low每次走一步。假如有环,两者一定会相遇(因为low一旦进入环中,可视为fast在后面追赶low的过程,每次两者都接近一步,最后一定能相遇)。
证明结论2:
设:
链表头到环入口长度为a,
环入口到相遇点长度为b,
相遇点到环入口长度为c

则:相遇时
快指针路程 = a+(b+c)k+b,k>=1 其中b+c为环的长度,k为绕环的圈数(K >= 1,即最少一圈,不能是0圈,不然和慢指针走到一样长,矛盾)
慢指针路程 = a + b
快指针走的路程是慢指针的两倍,所以:
(a + b) * 2= a+(b+c)k + b
化简可得:
a = (k-1)(b+c)+c,即链表头到环入口的长度等于相遇点到环入口的距离+(k-1)倍的环长度。其中K>=1,所以k-1>=0圈,所以两个指针分别从链表头和相遇点出发,每次走一步,最终一定相遇于环入口。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        ListNode* fast = pHead,*low = pHead;
        while(fast && fast->next)
        {
            fast = fast ->next->next;
            low = low->next;
            if(low == fast)
                break;
        }
        if(!fast || !fast->next)
            return NULL;
        low = pHead;
        while(fast != low)
        {
            fast = fast->next;
            low = low->next;
        }
        return low;
    }
};

还有一种方法,虽然对原本的数据结构进行了破坏,但对本题不乏是一种新奇有效的解法
设立两个指针,一个在左(previous),一个在右(front),previous指针紧跟front指针,每向前移动时就将previous指针的next赋为NULL,此时已经将数据结构损坏,最后将previous所指向的即为所求。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(!pHead->next)
        {
            return NULL;
        }
        ListNode* previous = pHead;
        ListNode *front = pHead->next;
        while(front)
        {
            previous->next = NULL;
            previous = front;
            front = front->next;
        }
        return previous;
    }
};

由于对原始数据结构存在破坏,所以在实际中也许存在一定的争议。

posted @ 2020-04-11 21:58  牛犁heart  阅读(156)  评论(0编辑  收藏  举报