思路:先找到环中的一个节点,然后从这个节点出发去统计环中的节点的数目 n。
然后设以快慢指针, 快指针先走n步,之后
然后快慢指针同时走,如果快慢指针碰头了就是链表的环的入口地址了。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode * nodes_of_loop = nodesInLoop(head);//找到链表的环的任意一个节点
if(nodes_of_loop == nullptr )
return nullptr;
int num = getNum(nodes_of_loop);
ListNode * slow = head;
ListNode * fast = head;
for(int i = 0; i < num; i++)//先走Num步数
fast = fast->next;
while(fast != slow ){//然后一起走
fast = fast->next;
slow = slow->next;
}
return fast;
}
ListNode * nodesInLoop(ListNode * head){//查找链表的环中的节点
if(head == nullptr )
return nullptr;
ListNode * slow = head;
ListNode * fast = slow->next;
while(slow && fast){
if(slow == fast)//链表有环,且找到环的一个节点
return slow;
slow = slow->next;
fast = fast->next;
if(fast)
fast = fast->next;
}
return nullptr ;
}
int getNum(ListNode * pNode){//统计环中的节点的数目
int sum = 1;
ListNode * p = pNode ;
while(p->next && p->next != pNode){
p = p->next;
sum++;
}
return sum;
}
};