# Summary of single linked list routine

### 21. Merge two sequential tables

Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
There is nothing to say about using an empty node.

```class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
dummy = ListNode()
p = dummy
while l1 and l2:
if l1.val < l2.val:
dummy.next = l1
dummy = dummy.next
l1 = l1.next
else:
dummy.next = l2
dummy = dummy.next
l2 = l2.next
while l1:
dummy.next = l1
dummy = dummy.next
l1 = l1.next
while l2:
dummy.next = l2
dummy = dummy.next
l2 = l2.next
return p.next
```

### 23. Merge K ascending lists

Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]

```class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
import heapq
heapMin = []
for ls in lists:
while ls:
heapq.heappush(heapMin, ls.val)
ls = ls.next
dummy = ListNode(0)
p = dummy
while heapMin:
p.next = ListNode(heapq.heappop(heapMin))
p = p.next
return dummy.next
```

Use the minimum heap to sort all elements of all lists, and then put them into the linked list in turn.
Use of heap:

```import heapq
heapq.heappush(heapMin, ls.val)
heapq.heappop(heapMin)
```

### 19. Delete the penultimate node of the linked list

Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]

Try using a single scan implementation.

You can let p1 take step k first. Now p1 only needs to take step n-k to reach the end of the linked list. At this time, p2 points to the head node and goes back. When p1 goes to the end, p2 goes to the penultimate node.
In this way, the penultimate k-th node is obtained.

```class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
while k:
p1 = p1.next
k = k - 1
while p1:
p2 = p2.next
p1 = p1.next
return p2
dummy = ListNode(0)
x = findFromEnd(dummy, n+1)
x.next = x.next.next
return dummy.next
```

However, note that we also use the technique of virtual head node to prevent the occurrence of null pointer. For example, the linked list has a total of 5 nodes. The topic asks you to delete the penultimate node, that is, the first node. According to the algorithm logic, you should first find the penultimate node. But there is no node in front of the first node, which will make an error.

Whenever the slow pointer slow advances one step, the fast pointer fast advances two steps.

If fast finally encounters a null pointer, it indicates that there is no ring in the linked list; If fast finally meets slow, it must be that fast exceeds slow by one circle, indicating that the linked list contains rings.

It can be seen that when the fast and slow pointers meet, let either pointer point to the head node, and then let them move forward at the same speed. The node position when they meet again is the beginning of the ring.

We assume that when the fast and slow pointers meet, the slow pointer slow takes k steps, so the fast pointer fast must take 2k steps
Fast must have taken k steps more than slow. In fact, this extra k step is that the fast pointer rotates in a circle in the ring, so the value of k is an "integer multiple" of the length of the ring.
Assuming that the distance between the meeting point and the starting point of the ring is m, combined with the slow pointer in the figure above, the distance between the starting point of the ring and the head node is k - m, that is, if you move K - M steps forward from the head, you can reach the starting point of the ring.

Coincidentally, if you continue to go k - m steps from the meeting point, you also happen to reach the starting point of the ring. Because in combination with the fast pointer in the figure above, you can go back to the meeting point by taking k steps from the meeting point. Then you must go to the starting point of the ring by taking k - m steps:
Therefore, as long as we re point any one of the fast and slow pointers to the head, and then the two pointers move forward at the same speed, we will meet after k - m steps, and the place where we meet is the starting point of the ring.

```    def detectCycle(self, head: ListNode) -> ListNode:
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if fast == slow:
break
if fast == None or fast.next== None:
# Indicates that there is no ring
return None
# Re point to the head node
# The speed pointer is synchronized, and the intersection point is the starting point of the ring
while slow != fast:
fast = fast.next
slow = slow.next
return slow
```

### 876. Intermediate node of linked list

Whenever the slow pointer slow advances one step, the fast pointer fast advances two steps. In this way, when fast reaches the end of the linked list, slow points to the midpoint of the linked list.

```class Solution:
def middleNode(self, head: ListNode) -> ListNode:
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
```

If it intersects, your algorithm should return the intersecting node; If there is no intersection, null is returned.
Therefore, we can let p1 traverse list a and then start to traverse List B, and p2 traverse List B and then start to traverse list A. This is equivalent to "logically" connecting the two lists together.

If the splicing is carried out in this way, p1 and p2 can enter the common part at the same time, that is, reach the intersection node c1 at the same time:
Then you may ask, if there is no intersection point between the two linked lists, can null be returned correctly?

This logic can cover this situation, which is equivalent to that c1 node is a null null null pointer, which can correctly return null.

```class Solution:
while p1!= p2:
if p1 == None: