方法一
快慢指针 寻找环
第一个指针 一次走1, 快指针一次走2
易得第一次相遇时 慢指针一定没有走完一圈,
故慢指针的 路程为X+Y
则快指针路径 为 2X+2Y
我们把慢指针回退到b
那么快指针距离B路程为 y 就是说 快指针距离b点路程为y时路程为2x
我们还可以直到2x+y就是b点
第一次相遇的点处为X+Y
我们把快指针放到a点 以1的速度 再次和慢指针相遇即为b点
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/class Solution {public:ListNode *entryNodeOfLoop(ListNode *head) {if(!head || !head->next) return 0;ListNode *first = head, *second = head;while(1) {if(second && second->next)second = second->next;elsereturn 0;first = first->next;second = second->next;if(first == second){first = head;while(first != second) {first = first->next;second = second->next;}return first;}}return 0;}};
方法二
给每一个地址一个哈希值,第一个出现两次的地址就环,否则遍历完链表自动退出,需要O(n)的空间
class Solution{public:unordered_map<ListNode*,int> h;ListNode *entryNodeOfLoop(ListNode *head){int id = 1;for(auto i = head;i;i = i->next,id++){if(h[i] != 0){return i;}else{h[i] = id;}}return NULL;}};
