LeetCode 142 環形鏈表 II

連接:https://leetcode-cn.com/problems/linked-list-cycle-iinode

給定一個鏈表,返回鏈表開始入環的第一個節點。 若是鏈表無環,則返回 null。c++

爲了表示給定鏈表中的環,咱們使用整數 pos 來表示鏈表尾鏈接到鏈表中的位置(索引從 0 開始)。 若是 pos 是 -1,則在該鏈表中沒有環。函數

說明:不容許修改給定的鏈表。spa

 

示例 :指針

輸入:head = [3,2,0,-4], pos = 1
輸出:tail connects to node index 1
解釋:鏈表中有一個環,其尾部鏈接到第二個節點。code

 

 

這道題的解法十分巧妙,只能膜拜。。用到了快慢指針,讓快慢指針同時走,可是快指針一次走兩步,慢指針一次走一步。能夠想象,當慢指針走到出現環的交點時,快指針已經走到環中的某個位置了。假設慢指針走了x步到達交點,那麼快指針此時已經走了2x步。假設快指針還要走y步再次到達交點,那麼當慢指針從交點出發再走y步時,快慢指針相遇,這是由於快指針的速度是慢指針的2倍。當快慢指針相遇時,讓慢指針指向頭節點,快指針依然在相遇的位置,這時讓快慢指針都是一次走一步,那麼當快慢指針再次相遇的時候,就是所求的出現環的交點。這是由於,慢指針從頭節點走x步到達交點,和以前同樣。而快指針從相遇位置也是再走x步到達交點。blog

這道題畫個圖就很清楚,環的位置實際上是求快慢指針再次相遇時所在位置。索引

若是不存在環,那麼快慢指針不會走到環中去,因爲快指針走的快,因此它會一直走到空。當出現空的時候,說明不存在環,函數直接返回空就好。leetcode

c++代碼以下:io

 1 class Solution {
 2 public:
 3     ListNode *detectCycle(ListNode *head) {
 4         auto slow = head, fast = head;
 5         while(fast){
 6             fast = fast->next;
 7             slow = slow->next;
 8             if(fast){
 9                 fast = fast->next;
10             }
11             else break;
12             
13             if(fast == slow){
14                 slow = head;
15                 while(fast != slow){
16                     fast = fast->next;
17                     slow = slow->next;
18                 }
19                 return slow;
20             }
21         }
22         return NULL;
23     }
24 };

在寫代碼的時候,出現了一個bug,看了很久纔看出來,錯誤代碼以下:

 1 class Solution {
 2 public:
 3     ListNode *detectCycle(ListNode *head) {
 4         auto slow = head, fast = head;
 5         while(fast){
 6             if(slow != fast){
 7                 slow = slow->next;
 8                 fast = fast->next;
 9                 if(fast){
10                     fast = fast->next;
11                 }
12                 else break;
13             }
14             else{
15                 slow = head;
16                 while(slow != fast){
17                     slow = slow->next;
18                     fast = fast->next;
19                 }
20                 return fast;
21             }  
22         }
23         return NULL;
24     }
25 };

思路是同樣的,當快慢指針沒有相遇的時候,兩個指針以不一樣的速度向前走,直到相遇時讓慢指針回到頭節點再開始走,直到快慢節點在交點相遇。區別在於第二個代碼先判斷了快慢指針是否相遇,而在初始化時快慢指針都指向頭節點,因此第6行的判斷是不成立的,裏面的語句並無執行。仍是要多練習,才能避坑呀。

相關文章
相關標籤/搜索