题解 | #链表中环的入口结点#

链表中环的入口结点

https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4

快慢指针的解法关键在于,当快慢指针相遇时,该节点与入口节点的距离=起始节点到入口节点的距离:

起始节点到入口节点距离为a,环上节点为b,快指针走了f步,慢指针走了s步,于是当他俩相遇时:

1)f = 2s

2)相遇节点与入口节点的顺时针距离为a

能得出第二个结论是由于:

当慢指针走到入口时,快指针必定走了2a步,即在环内已经走了a步(若a>=b,则走了至少1圈;若a<b,则尚未走满一圈)。

此时快指针与慢指针距离为a步,还需要相对多走b-a步快指针才能套圈遇到慢指针,又由于相对速度是倍数关系,因此慢指针还需要走b-a步。当然特殊情况下b=a,此时已经相遇。

所以,以顺时针为例:入口节点->相遇节点距离=b-a,相遇节点->入口节点距离=a,只需要分别从相遇节点和起始节点同步走a步即可在入口相遇。

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

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务