Linked List Cycle
141. Linked List Cycle
題目鏈接:https://leetcode.com/problems/linked-list-cycle/#/description
題目大意:給定一個鏈表,判斷是否有環,要求不能申請額外的空間
思路:使用快慢指針。fast指針一次移動兩步,slow指針一次移動一步。如果有環,則fast一定會和slow相遇。可以假設fast越過了slow而沒有相遇,且slow出於位置i,fast處於位置i+1,那麽,在前一步,slow就處於位置i-1,fast處於位置((i+1)-2)或i-1。也就是說,兩者相遇了。假定這個鏈表有一部分不存在環路,長度為k。slow沒走p步,fast就會走2p步。因此slow走了k步進入環路部分時,fast已經總共走了2k步,進入環路部分已有k步。由於k可能比環路長度大得多,實際上應該為mod(k, loop_len),並用k表示。即slow處於環中的0步位置,fast處於環中的k步位置,slow落後於fast,相距k步,或者說fast落後於slow,相距loop_len-k步。從fast落後於slow來看,fast現在落後slow loop_len-k步,並且每經過一個移動,fast就走近slow一步,那麽兩者將在loop_len-k次移動之後相遇。
算法復雜度:時間復雜度O(n),空間復雜度O(1)
代碼:
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 bool hasCycle(ListNode *head) { 12 ListNode *slow = head, *fast = head;13 while (fast && fast->next) { 14 slow = slow->next; 15 fast = fast->next->next; 16 if (slow == fast) 17 return true; 18 } 19 return false; 20 } 21 };
評測系統上運行結果:
142. Linked List Cycle II
題目鏈接:https://leetcode.com/problems/linked-list-cycle-ii/#/description
題目大意:給定一個鏈表,如果有環,返回環的起點,如果沒環,返回nullptr。要求不能修改鏈表。
思路:使用快慢指針。fast指針一次移動兩步,slow指針一次移動一步。如果有環,則fast一定會和slow相遇。可以假設fast越過了slow而沒有相遇,且slow出於位置i,fast處於位置i+1,那麽,在前一步,slow就處於位置i-1,fast處於位置((i+1)-2)或i-1。也就是說,兩者相遇了。假定這個鏈表有一部分不存在環路,長度為k。slow沒走p步,fast就會走2p步。因此slow走了k步進入環路部分時,fast已經總共走了2k步,進入環路部分已有k步。由於k可能比環路長度大得多,實際上應該為mod(k, loop_len),並用k表示。即slow處於環中的0步位置,fast處於環中的k步位置,slow落後於fast,相距k步,或者說fast落後於slow,相距loop_len-k步。從fast落後於slow來看,fast現在落後slow loop_len-k步,並且每經過一個移動,fast就走近slow一步,那麽兩者將在loop_len-k次移動之後相遇。假設這個位置為meetspot,meetspot與環路起始處相距k個結點,同時知道鏈表的頭部距離環路起始處也是k個結點。若用一個指針指向meetspot,另一個指針指向鏈表的頭部,兩者與環路起始處均相距k個結點,以同樣的速度移動,這兩個指針就會在k步之後相遇在環路的起始處。
算法復雜度:時間復雜度O(n),空間復雜度O(1)
代碼:
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 ListNode *slow = head, *fast = head; 13 while (fast && fast->next) { 14 slow = slow->next; 15 fast = fast->next->next; 16 if (slow == fast) { 17 fast = head; 18 while (slow != fast) { 19 slow = slow->next; 20 fast = fast->next; 21 } 22 return fast; 23 } 24 } 25 return nullptr; 26 } 27 };
評測系統上運行結果:
Linked List Cycle