链表中环的入口节点★★★

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
 
解题思路:
使用快慢指针,慢指针p1一次走1步,快指针一次走2步,首先如果有环,那么必定会在环中某个位置相遇,且此时快指针比慢指针多走了一个环的距离。
我们假设从头节点到入口节点的距离是a,从入口节点到相遇点的距离为b,从相遇点到入口的距离为c,环中顺时针走。那么a+(b+c)k+b是相遇点时快指针p2走的距离,其中k表示走的圈数且k>=1,a+b是相遇点时慢指针p1走的距离,2*(a+b) = a+(b+c)*k+b,简化得到a=(k-1)(b+c)+c,意义是从头节点到入口点的距离=从相遇点到入口点的距离+(k-1)圈,k大于等于1,则表示从头结点向后走必定与相遇点顺时针走在入口节点相遇。
 
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        ListNode *p1 , *p2;
        p1 = pHead;
        p2 = pHead;
        //找到环中第一次相遇的节点
        while(p1 != NULL && p2!= NULL){
            p1 = p1->next;
            p2 = p2->next;
            if(p2 == NULL){
                break;
            }else{
                p2 = p2->next;
            }
            if(p1 == p2){
                break;
            }
        }
        //无环
        if(p1 == NULL || p2 == NULL){
            return NULL;
        }
        p2 = pHead;
        //再次相遇的地方就是入口节点
        while(p2 != p1){
            p1 = p1->next;
            p2 = p2->next;
        }
        return p1;
    }
};

  

posted @ 2019-04-12 17:09  tcgoshawk  阅读(121)  评论(0编辑  收藏  举报