# Introduction to algorithm C-19. Delete the penultimate node of the linked list

Keywords: C Algorithm linked list

LeetCode problem brushing - algorithm learning plan (Introduction)

# Introduction of ideas

Personal idea: first find out which node to delete is the first node of the linked list (index=len + 1 -n). If it is the first node (head), move the head to the right (head = head - > next); If it is not the head node, use a linked list pointer tmp to point to the previous node of the node to be deleted, and finally connect the next node of the next node of tmp to the back of tmp (tmp - > next = tmp - > next - > next).

# My first correct submission

```/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     struct ListNode *next;
* };
*/

//Get linked list length
int GetListNodeLen(struct ListNode* head)
{
int len = 1;
struct ListNode *tmp = head;
if(tmp == NULL)
return 0;
while(tmp->next != NULL)
{
len++;
tmp = tmp->next;
}
return len;
}

struct ListNode* removeNthFromEnd(struct ListNode* head, int n)
{
int i = 0;
struct ListNode *tmp = head;
int len = GetListNodeLen(head);   //Get linked list length
int index = len + 1 - n;          //Serial number of the linked list node to be deleted (starting from 1)
if(index == 1)                    //If the node to be deleted is a header node
{
}
for(i = 1; i < index - 1; i++)    //Move tmp to the previous node where you want to delete the node
{
tmp = tmp->next;
}
tmp->next = tmp->next->next;      //Connect the next node of the node to be deleted after its previous node
}
```

# Official version

Here is the official version

## Method 1: calculate the length of the linked list

An easy way to think of is that we first traverse the linked list from the node to get the length L of the linked list. Then we traverse the linked list from the first node. When we traverse to the L − n+1 node, it is the node we need to delete.
In order to be consistent with n in the title, the number of nodes starts from 1, and the head node is the node numbered 1.
In order to facilitate the deletion operation, we can traverse L − n+1 nodes from the dummy node. When traversing the L − n+1 node, its next node is the node we need to delete, so we only need to modify the pointer once to complete the deletion operation.
——Author: leetcode solution

This is the method I used, but dummy nodes (dummy - > Val = 0, dummy - > next = head;) are used here

```int getLength(struct ListNode* head) {
int length = 0;
++length;
}
return length;
}

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0, dummy->next = head;
int length = getLength(head);
struct ListNode* cur = dummy;
for (int i = 1; i < length - n + 1; ++i) {
cur = cur->next;
}
cur->next = cur->next->next;
struct ListNode* ans = dummy->next;
free(dummy);
return ans;
}

Author: LeetCode-Solution
Source: force buckle( LeetCode)
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.
```

Complexity analysis
Time complexity: O(L), where l is the length of the linked list.
Space complexity: O(1).

## Method 2: stack

We can also put all nodes on the stack in turn while traversing the linked list. According to the "first in, last out" principle of the stack, we pop up that the nth node on the stack is the node to be deleted, and the current node on the top of the stack is the precursor node of the node to be deleted. In this way, the deletion operation becomes very convenient.
——Author: leetcode solution

```struct Stack {
struct ListNode* val;
struct Stack* next;
};

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0, dummy->next = head;
struct Stack* stk = NULL;
struct ListNode* cur = dummy;
while (cur) {
struct Stack* tmp = malloc(sizeof(struct Stack));
tmp->val = cur, tmp->next = stk;
stk = tmp;
cur = cur->next;
}
for (int i = 0; i < n; ++i) {
struct Stack* tmp = stk->next;
free(stk);
stk = tmp;
}
struct ListNode* prev = stk->val;
prev->next = prev->next->next;
struct ListNode* ans = dummy->next;
free(dummy);
return ans;
}

Author: LeetCode-Solution
Source: force buckle( LeetCode)
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.
```

Complexity analysis
Time complexity: O(L), where l is the length of the linked list.
Space complexity: O(L), where l is the length of the linked list. It is mainly the overhead of the stack.

## Method 3: double pointer

We can also solve this problem without preprocessing the length of the linked list and using the constant space. See Official explanation

```struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0, dummy->next = head;
struct ListNode* first = head;
struct ListNode* second = dummy;
for (int i = 0; i < n; ++i) {
first = first->next;
}
while (first) {
first = first->next;
second = second->next;
}
second->next = second->next->next;
struct ListNode* ans = dummy->next;
free(dummy);
return ans;
}

Author: LeetCode-Solution
Source: force buckle( LeetCode)
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.
```

Complexity analysis
Time complexity: O(L), where l is the length of the linked list.
Space complexity: O(1).

Here is my failed submission record

```/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     struct ListNode *next;
* };
*/

//Get linked list length
int GetListNodeLen(struct ListNode* head)
{
int len = 1;
struct ListNode *tmp = head;
if(tmp == NULL)
return 0;
while(tmp->next != NULL)
{
len++;
tmp = tmp->next;
}
return len;
}

struct ListNode* removeNthFromEnd(struct ListNode* head, int n)
{
int i = 0;
struct ListNode *tmp = head;
int len = GetListNodeLen(head);   //Get linked list length
int index = len + 1 - n;          //Serial number of the linked list node to be deleted (starting from 1)
if(index == 1)                    //If the node to be deleted is a header node
{
tmp = tmp -> next;
}
for(i = 1; i < index - 1; i++)    //Move tmp to the previous node where you want to delete the node
{
tmp = tmp->next;
}
tmp->next = tmp->next->next;      //Connect the next node of the node to be deleted after its previous node
}
```

This code is actually different from the successfully submitted version in two lines: (struct ListNode *tmp = head;)

error code

```    if(index == 1)                    //If the node to be deleted is a header node
{
tmp = tmp -> next;
}
```

After submitting the successful version, by contrast, I found that the above way of writing, the head is overwritten by me... [you can have no header node, but you can't have no header pointer]
This error can be avoided through the dummy node in the official problem solution, so you don't have to make the following judgment.

```    if(index == 1)                    //If the node to be deleted is a header node
{