Problem Description
For a given linked list, return the entry node of the ring. If there is no ring, return null to
expand:
Can you give a solution that does not use extra space?
Input description:
Input a linked list
Output description:
the entry node of the output ring
Example
Example 1
Enter
{-3,-2,-1,0,1,2,3,4,0 (circular)}
Output
{0}
Solutions
analysis
- Hash table (using extra space): Find the entry of the circular linked list by traversing records to the hash table
Time responsibility: O(n)
Space responsibility: O(n) - Fast and slow pointer (without using extra space): It is realized by the way of fast and slow pointer, which will be introduced in detail below:
Demonstration process: (Note that the starting point of the fast and slow pointers is 0)
Suppose there is a ring in the linked list, the length of the ring is b, and the length of the non-ring is b
1. Calculate the distance traveled by fast and slow, here we assume that they have gone Meet after n laps
fast = 2slow
fast = slow + nb
formula scale is equal:
2slow = slow + nb get
:
slow = nb
fast = 2nb
-------------------- --------------
2. How many steps can I take to get to the entrance
enter = a + nb
----------------------- -----------
3. The second encounter between fast pointer and slow
fast = 0;
slow = nb; both
fast and slow pointers have gone a step:
fast = a;
slow = a + nb
this When they met at the entrance
method
- Through the Hasay table.
- Through the speed pointer, the picture below is the demonstration process, and the picture adopts the picture of Likou
Code
// 思路1
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode pos = head;
Set<ListNode> visited = new HashSet<ListNode>();
while (pos != null) {
if (visited.contains(pos)) {
return pos;
} else {
visited.add(pos);
}
pos = pos.next;
}
return null;
}
}
// 思路2
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (true) {
if (fast == null || fast.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
break;
}
}
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
If you want to test, you can go directly to the link of Niuke.com to do the test