2014.1.13 21:43
Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Follow up:
Can you solve it without using extra space?
Solution:
This problem doesn't only ask you to check if there is a loop in the list, but also to find out where you enter the loop.
It is a bit tricky to solve this problem, if you are too accustomed to that "chasing method" that we mentioned in Linked List Cycle.
Since you only have a "next" pointer, what you can do is to check if $ptr or $ptr->next satisfy some specific property.
See the following linked list:
Node 2 is the entrance of the loop. Both node 1 and node 4 points to it. If you start traversing the list, you are sure to reach node 2 first and node 4 later. If there is a $ptr pointing to node 4, you reach $ptr->next before you reach $ptr,right? In a normal linked list, this will never happen. That's how we use abnormal condition to detect this abnormal node.
This problem doesn't use a chasing strategy with two pointers. But it requires one-by-one probing for all nodes until the right one is found, with each probing having O(n) time complexity. Therefore, the overall time complexity is O(n^2), space complexity is O(1).
Accepted code:
1 // 1CE, 2TLE, 1AC, foolish mistake.. 2 /** 3 * Definition for singly-linked list. 4 * struct ListNode { 5 * int val; 6 * ListNode *next; 7 * ListNode(int x) : val(x), next(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 ListNode *detectCycle(ListNode *head) { 13 // IMPORTANT: Please reset any member data you declared, as 14 // the same Solution instance will be reused for each test case. 15 if(head == nullptr){ 16 return nullptr; 17 } 18 19 ListNode *ptr, *res; 20 21 res = head; 22 while(res != nullptr){ 23 ptr = head; 24 // Forgot to check nullptr, added by the way later. 25 while(ptr != res->next && ptr != nullptr){ 26 if(ptr == res){ 27 // ptr reaches res first, not what we expect 28 break; 29 } 30 // 1TLE here, forgot to move forward... 31 // 1CE here, ';' is missing!!!! 32 ptr = ptr->next; 33 } 34 if(ptr == res->next){ 35 // $ptr reaches res->next first, that means $res->next is the start of the loop 36 // while $res is the end of the loop, thus $ptr = $res->next is the result we want 37 return ptr; 38 }else{ 39 // 1TLE here, forgot to move forward.. 40 res = res->next; 41 } 42 } 43 44 return nullptr; 45 } 46 };