一、题目
二、代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
/*
思路:(1)快慢指针法判断是否有环 快的走两步 慢的走一步 步数差别为1 相当于追赶,一定会在环中间相遇
(2) x为环起始节点 y为相遇节点 z为剩余环长度
由快慢属性可知 2(x+y)=x+y+n(y+z)
x=n(y+z)-y 负数不如正数,多一圈少一圈一样
x=(n-1)(y+z)+Z n=1时,从源节点出发和相遇节点出发,相交为环入口
n>1时,从源节点出发和相遇节点出发,相交为环入口(从相遇节点出发的走了n圈)
*/
///统一链表格式
ListNode* dummyhead = new ListNode(0); //设置虚假的头结点 为了使得单节点和多节点情况统一
dummyhead->next = head;
ListNode* fast_node = new ListNode(0);
fast_node=dummyhead;
ListNode* low_node = new ListNode(0);
low_node=dummyhead;
ListNode* begin_source = new ListNode(0);
begin_source=dummyhead;
ListNode* begin_meet = new ListNode(0);
ListNode* return_node = new ListNode(0);
if(fast_node->next==nullptr||fast_node->next->next==nullptr) return nullptr;//如果节点格数为0或者1 返回nullptr
else
{
fast_node=fast_node->next->next;
low_node=low_node->next;
while(fast_node!=low_node) //在循环中,如果是有环的节点 一定能够相遇 如果出现了nullptr 说明一定无环
{
if(fast_node->next==nullptr||fast_node->next->next==nullptr) return nullptr;
else
{
fast_node=fast_node->next->next;
low_node=low_node->next;
}
}
//如果函数没有直接返回走到了这一步 说明快和慢相遇在了x+y处,此时新建节点开始跑,会相遇在环入口处
begin_meet=fast_node;
while(begin_meet!=begin_source)
{
begin_source=begin_source->next;
begin_meet=begin_meet->next;
}
//退出时的节点即为所求
return_node=begin_meet;
}
return return_node;
}
};