以前想了好几次没想明白,早上拿笔纸一画就看出来了;
设置slow,fast两个指针,slow每次移动一步,fast每次移动两步;若fast结束前与slow重合则说明有环,若未重合即结束则说明没有环;
第一次重合时,假设从head到环起始位置距离为k,slow移动了n步,则slow在环中移动了n-k步,fast在环中移动了2n-k步;距离差n为环长度的倍数;
所以slow再移动k步将到达环的起始位置;这时再从head出发一个finder指针,移动k步恰好也到了环的起始位置,所以当slow==finder的位置即为所求;
代码:
1 public ListNode detectCycle(ListNode head) { 2 if(head == null) return null; 3 ListNode fast = head; 4 ListNode slow = head; 5 do{ 6 slow = slow.next; 7 fast = fast.next; 8 if(slow==null || fast==null) return null; 9 fast = fast.next;10 if(fast==null) return null;11 }while(fast != slow);12 13 ListNode finder = head;14 while(finder != slow){15 finder = finder.next;16 slow = slow.next;17 }18 return finder;19 }