#include "s0142_linked_list_cycle.hpp" IterResult S0142::iter(ListNode *fast, ListNode *slow, bool startUp) { // 终止条件 if (fast == nullptr || slow == nullptr) { return {nullptr, false}; } if (fast->next == nullptr) { return {nullptr, false}; } if (slow->next == slow) { return {slow, true}; } // 当两指针相遇时同样达到终止条件 if (fast == slow && !startUp) { return {nullptr, true}; } // 递归 IterResult result = iter(fast->next->next, slow->next, false); // 从后往前遍历 // 达到了终止条件,但是没有两个指针遇见过 // 这说明没有环 if (!result.meet) { return {nullptr, false}; } else { // 有环的情况 // 我们把 fast 和 fast-next 节点所经过的足迹全部记录下来 // key 是所经过的节点 // value 是所经过的次数 if (footprint.count(fast) == 0) { footprint[fast] = 1; } else { footprint[fast] += 1; } if (footprint.count(fast->next) == 0) { footprint[fast->next] = 1; } else { footprint[fast->next] += 1; } // 什么情况下是环的入口呢? // 1. footprint[fast] == 1 && footprint[fast->next] > 1 // 2. footprint[fast->next] == 1 && footprint[fast->next->next] > 1 if (footprint.count(fast) == 1 && footprint.count(fast->next) == 1) { if (footprint[fast] == 1 && footprint[fast->next] > 1) { return {fast->next, true}; } } if (footprint.count(fast->next) == 1 && footprint.count(fast->next->next) == 1) { if (footprint[fast->next] == 1 && footprint[fast->next->next] > 1) { return {fast->next->next, true}; } } // 返回 return result; } } ListNode *S0142::detectCycle(ListNode *head) { if (head == nullptr) { return nullptr; } if (head->next == nullptr) { return nullptr; } // 递归函数无法处理所有节点都在环里的情况,所以在这里加一个哑节点 ListNode dummy = ListNode(0); dummy.next = head; return iter(&dummy, &dummy, true).node; }