# 19. Delete the penultimate node of the linked list

## subject

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

Input: head = [1], n = 1
Output: []
Example 3:

Input: head = [1,2], n = 1
Output: [1]

Tips:

The number of nodes in the linked list is sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

Source: LeetCode

## Problem solving - violence

To delete a node in the linked list, you need to know its previous node. For the head node, there is no previous node. Therefore, the virtual head node dummy needs to be defined

The x-th node of the linked list must be traversed.
The first traversal knows the length of the whole linked list, and converts the reciprocal node into the x-th node of the positive number
The second traversal deletes the penultimate node

```ListNode dummy = new ListNode(); //Add a node without data to unify the boundary node operation
int count = 1;
count++;
}
n = count - n + 1;//Delete nth from beginning to end
count = 1;
ListNode pre = dummy;
for(;count!=n;count++){
}//Found element to delete
//Delete
return dummy.next;
```

## Problem solving - hash table

Can you try using one scan implementation?

The second traversal is mainly to find the elements to be deleted, so if we use the hash table to record the location information at the first traversal, we don't need to traverse again.

```class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode();
HashMap<Integer,ListNode> map = new HashMap<>();
int count = 0;
map.put(count,dummy);
count++;
}
//Calculate the location of the deleted element
n = count-n+1;
//Gets the previous element and the current element of the element to be deleted
ListNode pre = map.get(n-1);
return dummy.next;
}
}
```

## Problem solving - double pointer

The previous linked list questions used double pointers. Here we consider double pointers. Double pointers are suitable for dividing intervals, distances, etc.

The main reason why you need to traverse is to find the length of the linked list, that is, you need to traverse to the back of the last node, and then locate the reciprocal node through the back of the last node. Here, we can use a pointer to point to the last node and a pointer to the previous node to be deleted.

The node to be deleted here is the penultimate node in the linked list. slow points to the previous node of the node to be deleted.
How to determine the position of slow? When the pointer fast points to null, there is a difference of 2 nodes between it and the pointer slow, which is exactly n=2.

Let fast take n+1 steps first, and then go together

```class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {

// The slow pointer initially points to the virtual header node
// The fast pointer initially points to the virtual header node

// The fast pointer moves forward n+1 steps first
for(int i = 0; i <= n; i++) {
fast = fast.next;
}

// The fast and slow pointers move forward at the same time until the fast pointer points to null
while (fast!=null){
fast = fast.next;
slow = slow.next;
}

// The next node of the slow pointer is the node to be deleted
ListNode delNode = slow.next;
// The subsequent pointer of the slow pointer points to the next node of the node to be deleted
// In this way, the node to be deleted is deleted
slow.next = delNode.next;
delNode.next = null;
}

}

```