# 【剑指】23.链表中环的入口结点

#### 题目描述

• 一个链表中包含环，找出环的入口结点。

#### 算法分析

• 设链表为1,2,3,...,n,...m 其中m指向n，形成环；可知链表长度为m，环长度为m-n+1，环的入口为n；
• 使得快慢指针均指向头结点，慢指针步长为1，快指针步长为2；两者相遇时，慢指针走了x步，此时块慢指针均指向1+x，即快指针比慢指针多走了一个环的长度，即1+x等于1+2x坐标，所以x等于环的长度m-n+1；
• 那么，此时快慢指针的位置为1+x=m-n+2，慢指针走到尾节点还需要n-2步，走到环入口，+1，还需要n-1步，若此时将某个节点从头结点走n-1步，则两者同时到达环入口节点。

class Solution {
public:
{
return nullptr;

while (fastNode && fastNode->next)
{
fastNode = fastNode->next;
fastNode = fastNode->next;

slowNode = slowNode->next;

if (fastNode == slowNode)
break;
}

if (!fastNode || !fastNode->next)
return nullptr;

while (fastNode != slowNode)
{
fastNode = fastNode->next;
slowNode = slowNode->next;
}

return fastNode;
}
};

// ==================== Test Code ====================
void Test(char* testName, ListNode* pHead, ListNode* entryNode)
{
if (testName != nullptr)
printf("%s begins: ", testName);
Solution s;
printf("Passed.\n");
else
printf("FAILED.\n");
}

// A list has a node, without a loop
void Test1()
{
ListNode* pNode1 = CreateListNode(1);

Test("Test1", pNode1, nullptr);

DestroyList(pNode1);
}

// A list has a node, with a loop
void Test2()
{
ListNode* pNode1 = CreateListNode(1);
ConnectListNodes(pNode1, pNode1);

Test("Test2", pNode1, pNode1);

delete pNode1;
pNode1 = nullptr;
}

// A list has multiple nodes, with a loop
void Test3()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);

ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode3);

Test("Test3", pNode1, pNode3);

delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
}

// A list has multiple nodes, with a loop
void Test4()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);

ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode1);

Test("Test4", pNode1, pNode1);

delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
}

// A list has multiple nodes, with a loop
void Test5()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);

ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode5);

Test("Test5", pNode1, pNode5);

delete pNode1;
pNode1 = nullptr;
delete pNode2;
pNode2 = nullptr;
delete pNode3;
pNode3 = nullptr;
delete pNode4;
pNode4 = nullptr;
delete pNode5;
pNode5 = nullptr;
}

// A list has multiple nodes, without a loop
void Test6()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);

ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);

Test("Test6", pNode1, nullptr);

DestroyList(pNode1);
}

// Empty list
void Test7()
{
Test("Test7", nullptr, nullptr);
}

int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();

return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120