链表求环【142】(medium)
#include <iostream>
#include <set>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
// 方法二、Floyd Cycle Detection Algorithm
ListNode *slow = head, *fast = head;
ListNode *meet = NULL;
while (fast && fast->next) {
// move slow by one pointer
slow = slow->next;
// move fast by two pointers
fast = fast->next->next;
// if they meet any any node, linked list contains a cycle
if (slow == fast) {
meet = fast; // fast与slow相遇, 记录相遇位置
break;
}
}
if (meet == NULL) // 没相遇, 无环
return NULL;
while (head && meet) {
if (head == meet) // head,meet相遇, 遇到环的起始位置
return head;
// head, meet 每次走1步
head = head->next;
meet = meet->next;
}
return NULL;
}
// ListNode *detectCycle(ListNode *head) {
// // 方法一、使用set
// std::set<ListNode *> node_set;
// while (head) {
// if (node_set.find(head) != node_set.end())
// // node_set.find()没走到end(), 则找到相同元素
// return head;
// node_set.insert(head);
// head = head->next;
// }
// return NULL;
// }
};
int main() {
ListNode a(1);
ListNode b(2);
ListNode c(3);
ListNode d(4);
ListNode e(5);
ListNode f(6);
ListNode g(7);
a.next = &b;
b.next = &c;
c.next = &d;
d.next = &e;
e.next = &f;
f.next = &g;
g.next = &c;
/**
* 1 -> 2 -> 3 -> 4 -> 5
* \ /
* <- 7 <- 6 <-
*
*/
Solution solve;
ListNode *node = solve.detectCycle(&a);
if (node)
cout << node->val << endl;
else
cout << "NULL";
return 0;
}