题目:一个链表中包含环,如何找出环的入口结点?
#include<iostream>
#include "List.h"
using namespace std;
//struct ListNode
//{
// int m_nValue;
// ListNode* m_pNext;
//};
//一.是否存在环
ListNode* IsLoopInList(ListNode* pHead) {
//中心思路:设置一快一慢两个指针 若有环 必能重合
//最终返回值为nullptr则无环 反之有环
if (pHead == nullptr) {//空链表
return nullptr;
}
ListNode* pSlow = pHead->m_pNext;
ListNode* pFast = nullptr;
if (pSlow != nullptr) {
pFast = pSlow->m_pNext;
}
while (pSlow != nullptr && pFast != nullptr) {
if (pSlow == pFast) {
return pFast;
}
pSlow = pSlow->m_pNext;
pFast = pFast->m_pNext;
if (pFast != nullptr) {
pFast = pFast->m_pNext;
}
}
return nullptr;//只有一个节点或者无环
}
ListNode* EntryOfLoopInList(ListNode* pHead) {
//二.环的个数n
if (pHead == nullptr || IsLoopInList(pHead)==nullptr) {//空链表或者无环链表
return nullptr;
}
ListNode* start = IsLoopInList(pHead);
ListNode* p = start->m_pNext;
int count = 1;
while (p != start) {
p = p->m_pNext;
count++;
}
//三.环的入口
//中心思路:一前一后两个同速度指针 前面的指针先走n步 两个指针相遇点即为环入口
ListNode* pFront = pHead;
ListNode* pBack = pHead;
for (int i = 0; i < count; i++) {
pFront = pFront->m_pNext;
}
while (pFront != pBack) {
pFront = pFront->m_pNext;
pBack = pBack->m_pNext;
}
return pFront;
}
int main() {
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);
//ListNode* res = IsLoopInList(pNode1);
ListNode* res = EntryOfLoopInList(nullptr);
return 0;
}
1.代码的鲁棒性
2.复杂问题分解为三个问题