链表中环的入口结点
1 # -*- coding:utf-8 -*- 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 class Solution: 7 def EntryNodeOfLoop(self, pHead): 8 # write code here 9 plist = [] 10 while pHead: 11 if pHead in plist: 12 return pHead 13 else: 14 plist.append(pHead) 15 pHead = pHead.next
return None
c++
链表头到环入口长度为--a
环入口到相遇点长度为--b
相遇点到环入口长度为--c
相遇时
快指针路程=a+(b+c)k+b ,k>=1 其中b+c为环的长度,k为绕环的圈数(k>=1,即最少一圈,不能是0圈,不然和慢指针走的一样长,矛盾)。
慢指针路程=a+b
快指针走的路程是慢指针的两倍,所以:
(a+b)*2=a+(b+c)k+b
化简可得:
a=(k-1)(b+c)+c 这个式子的意思是: 链表头到环入口的距离=相遇点到环入口的距离+(k-1)圈环长度。其中k>=1,所以k-1>=0圈。
所以两个指针分别从链表头和相遇点出发,最后一定相遇于环入口。
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 }; 9 */ 10 class Solution { 11 public: 12 ListNode* EntryNodeOfLoop(ListNode* pHead) 13 { 14 //先找相遇的指针 15 ListNode* fast=pHead; 16 ListNode* low=pHead; 17 while(fast!=nullptr && fast->next!=nullptr){ 18 fast=fast->next->next; 19 low=low->next; 20 if(fast==low) break; 21 } 22 //此时fast==low就是相遇的节点 23 if(!fast || fast->next==nullptr) return NULL; 24 low = pHead;//low从头节点出发,fast从相遇的节点出发 25 while(fast!=low){ 26 fast = fast->next; 27 low = low->next; 28 } 29 return fast; 30 } 31 };