題目描述
給定一個鏈表,返回鏈表開始入環的第一個節點。 如果鏈表無環,則返回 null
。
說明:不允許修改給定的鏈表。
進階:
你是否可以不用額外空間解決此題?
解題思路
分為三步:
- 首先判斷是否存在環,利用快慢指針法,從頭節點開始快指針每次走兩步,慢指針每次走一步,如果存在環則兩指針必定會相遇,如果沒有再次相遇則不存在環
- 然后找到環中節點的個數,此時快指針已經處在環內,所以讓其每次向前走一步,記錄再次和慢指針相遇時走的步數即為環中節點個數
- 找環入口節點時還是利用快慢指針,從頭節點開始先讓快指針走環中節點個數的步數,然后快慢指針同時向前移動,這樣相遇時快指針恰好比滿指針多走了一個環的長度,即指向了環入口節點
代碼
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *detectCycle(ListNode *head) { 12 if(head == NULL) return NULL; 13 ListNode *fast = head, *slow = head; 14 int len = 0; 15 while(fast->next && fast->next->next){ 16 fast = fast->next->next; 17 slow = slow->next; 18 if(fast == slow){ 19 len = 1; 20 break; 21 } 22 } 23 if(len == 0) return NULL; 24 while(fast->next != slow){ 25 fast = fast->next; 26 len++; 27 } 28 fast = head; 29 slow = head; 30 while(len-- > 0) 31 fast = fast->next; 32 while(fast != slow){ 33 fast = fast->next; 34 slow = slow->next; 35 } 36 return fast; 37 } 38 };