链表中环的入口节点

题目

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

思路

  1. 确定是否存在环。用两个指针,一快一慢,快的追上慢的,则包含环
  2. 找到环的入口。让快的指针先走n(环的长度)步,然后快慢指针以相同的速度向前推进,两指针相遇,则是环的入口
  3. 确定环的长度。定义两个指针,一块一慢,相遇时在环中,然后从相遇点出发,边走边计数,知道下次在走到相遇点
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* head)
    {
        if(!head||!head->next)//||!head->next
            return nullptr;
        
        ListNode *node=ringHead(head);
        if(!node)
            return nullptr;
        
        int len=getRingLength(node);
        ListNode *fast=head;
        for(int i=0;i<len;++i)
            fast=fast->next;
        ListNode *slow=head;
        while(fast!=slow)
        {
            fast=fast->next;
            slow=slow->next;
        }
        return fast;
    }
private:
    ListNode *ringHead(ListNode *head)
    {
        ListNode *fast=head->next;
        ListNode *slow=head;
        while(fast&&slow)
        {
            if(fast==slow)
                return fast;
            slow=slow->next;
            fast=fast->next;
            if(fast)
                fast=fast->next;
        }
        return nullptr;
    }
    int getRingLength(const ListNode *node)
    {
        int len=1;
        ListNode *tmp=node->next;
        while(tmp!=node)
        {
            ++len;
            tmp=tmp->next;
        }
        return len;
    }
};
原文地址:https://www.cnblogs.com/tianzeng/p/10178231.html