# Linked list - find entry ring node

Posted by Vinze on Sun, 09 Jan 2022 09:54:56 +0100

## subject

If a linked list contains a ring, the first node entering the ring from the chain header node in the direction of the next pointer is the ring entry node.
Now that the head node head is known, locate the entry node.

Idea:

Differential method - make n turns when the fast and slow pointers meet. Adjust the starting position so that they just meet at the entrance node.

Steps:
1. Locate the "meeting point" - the fast and slow pointer starts from the beginning at the same time to locate the ring meeting point (this action can also be used to judge whether the linked list has a ring and return a node in the ring, which is very useful!)
2.P1 starts from the head node, P2 starts from the meeting point, and then meets again, which is the entry node

Example (from q22 in Chapter 4 of sword finger Offer):

Given the pointer of the chain header node in the figure, the returned content should be the pointer of entry node 3

First create the example list:

```'''Define linked list nodes'''
class ListNode():
def __init__(self, item):
self.item = item
self.next = None

arr = [1,2,3,4,5,6]
n = len(arr)
for i in range(1,n):
node = ListNode(arr[i])
cur.next = node
cur = cur.next

'''Connect the ring'''
for i in range(0,5):
tail = tail.next
for i in range(0,2):
entry = entry.next
tail.next = entry```

After creating it, check the contents of the linked list to see if it is connected correctly

```'''Check circular linked list'''
arr_check = []
tag = 0
while(cur != None)&(tag<15):
arr_check.append(cur.item)
cur = cur.next
tag+=1
print(arr_check)```

The result output is as follows (cyclic output from the position of the ring, i.e. 1 2 3 4 5 6 - > 3 4 5 6 - > 3 4 5 6 - > 3...):

`[1, 2, 3, 4, 5, 6, 3, 4, 5, 6, 3, 4, 5, 6, 3]`

### Implement search

The solution class contains two functions:

-locateMeetNode() is responsible for finding the "encounter node" and judging whether the linked list has a ring

-findEntry() is responsible for pushing out the entry node by using the encounter node

```class Solution():
'''Step 1 locate meet node - fast vs slow'''
def locateMeetNode(self, head: ListNode) -> ListNode:
print('List chain not exist or contains 1 node only.')
return None
else:
fast = slow.next
while(fast != None)&(slow != None):
if(fast == slow):
return slow
slow = slow.next
fast = fast.next
if(fast != None):
fast = fast.next
'''if the loop ends without returning anything, then there is no circle in list chain'''
print('This list chain contains no circle.')
return None

'''Step 2 start from meet node - meet again'''
def findEntry(self, head: ListNode) -> ListNode:
if(p2 == None):
print('No entry because there is no circle.')
return None
while(p1 != p2):
p1 = p1.next
p2 = p2.next
return p1
```

### Test code:

1. Check whether the meeting point is correct. According to the linked list of this question, it should be 5

```s1 = Solution()
meet.item```

Result output: 5

2. Check whether the entry node is correct. According to the linked list, it should be 3

```entry = s1.findEntry(h1)
entry.item```

Result output: 3

### Reflection: stuck place

1. Instantiation of solution class s1=Solution() takes 15 minutes to find the reason and try to reconstruct the function for 15 minutes, which is about half an hour in total
2. Extreme cases that must be considered when using the double pointer method: head = = None, head Next = = None returns None directly
3. Double pointer loop loop control sequence: first compare the pointers, then walk, and then fast needle empty check + 1 step
4. Careless problem: typo writes the starting point of the fast pointer incorrectly, resulting in debugging for 10 minutes

In the follow-up practice, we should continue to consolidate the foundation and prevent careless problems, so as to reduce the debug time.