Delete the middle of a Linked List

Introduction

The linked list is one of the most important data structures to learn while preparing for interviews. Having a good grasp of Linked Lists can be a huge plus point in a coding interview.

Problem Statement

In this problem, we are given a singly linked list. We have to delete the middle node of the given list.

Problem Statement Understanding

Let’s try to understand the problem statement with an example.

The middle node of this list is 6. We have to remove the middle node from the list. After we remove the middle node, the final linked list will look like this:

Now,

The middle node of this list is 6. We have to remove the middle node from the list. After we remove the middle node, the final linked list will look like this:

This question is not a very complex one. We can easily think of a Brute force solution, in which we find the length of the linked list, store it in an integer N and then delete the (N/2)th node from the list, with the help of a simple deletion process.

Let us have a glance at the above approach.

Approach and Algorithm (Brute Force)

The approach is going to be pretty simple.

  • Firstly, we will count the number of nodes in the given list and store it in a variable N.
  • Then we will find the position of the middle node, which will be equal to mid = (N/2).
  • Now we will traverse the list from head while(mid-- >1).
  • When the above condition of while(mid-- > 1) violates, we will delete the middle node by performing following operation currrentNode → next = currentNode → next → next.

In this way, the link gets successfully changed, and the middle nodes gets deleted.

Time Complexity - O(N), as no nested traversal is needed.
Space Complexity - O(1), as only temporary variables are being created.

Can we solve this question without actually finding the length of the linked list?

Yes. We can use the slow and fast pointer method to find the middle of the given linked list. This method is the most efficient when it comes to finding the middle of a linked list. The slow and fast method is explained in detail in the next approach.

Approach (Slow and Fast pointer method)

The approach is going to use the two pointers method. We are going to create two pointers, say slow and fast. Both the pointers will point to the head initially. Now, the slow pointer will take one step, while the fast pointer will take two steps. When the fast pointer will reach the node, the slow pointer will be pointing to the middle node. In every iteration, we will also store the slow pointer in a temp variable before incrementing it.

So, we now have the node just before the middle node. We will simply change the links now.

Algorithm

  • Base case 1 - If the head is NULL, return NULL.
  • Base case 2 - If the head is the only node in the list, delete the head and return NULL.
  • Create the slow and fast pointer, both will be initiated at the head.
  • Make the fast pointer take two steps and the slow pointer 1 step. In every iteration, before incrementing the slow pointer, we will store it in a temp variable.
  • When the fast pointer reaches the end, the slow pointer will be pointing to the middle node, and the temp will be pointing to the (middle-1)th node.
  • Now, to change the links - make the temp point to the next of the slow pointer.
  • In the end, delete the slow pointer and return NULL.

Dry Run

Code Implementation



#include 
using namespace std;

struct Node {
    int data;
    struct Node* next;
};

struct Node* deleteMid(struct Node* head)
{
    
    if (head == NULL)
        return NULL;
    if (head->next == NULL) {
        delete head;
        return NULL;
    }

    struct Node* slow_pointer = head;
    struct Node* fast_pointer = head;

struct Node* prev;
    while (fast_pointer != NULL
&& fast_pointer->next != NULL) {
        fast_pointer = fast_pointer->next->next;
        prev = slow_pointer;
        slow_pointer = slow_pointer->next;
    }

    prev->next = slow_pointer->next;
    delete slow_pointer;
 
    return head;
}

void printList(struct Node* ptr)
{
    while (ptr != NULL) {
        cout << ptr->data << "->";
        ptr = ptr->next;
    }
    cout << "NULL\n";
}

Node* newNode(int data)
{
    struct Node* temp = new Node;
    temp->data = data;
    temp->next = NULL;
    return temp;
}

int main()
{

    struct Node* head = newNode(1);
    head->next = newNode(2);
    head->next->next = newNode(6);
    head->next->next->next = newNode(13);
 
    cout << "Given Linked List\n";
    printList(head);
 
    head = deleteMid(head);
 
    cout << "Linked List after deletion of middle\n";
    printList(head);
 
    return 0;
}


public class PrepBytes {


    static class Node {
        int data;
        Node next;
    }

    static Node deleteMid(Node head)
    {

        if (head == null)
            return null;
        if (head.next == null) {
            return null;
        }

        Node slow_ptr = head;
        Node fast_ptr = head;

        Node prev = null;

        while (fast_ptr != null
&& fast_ptr.next != null) {
            fast_ptr = fast_ptr.next.next;
            prev = slow_ptr;
            slow_ptr = slow_ptr.next;
        }

        prev.next = slow_ptr.next;

        return head;
    }

    static void printList(Node ptr)
    {
        while (ptr != null) {
            System.out.print(ptr.data + "->");
            ptr = ptr.next;
        }
        System.out.println("NULL");
    }

    static Node newNode(int data)
    {
        Node temp = new Node();
        temp.data = data;
        temp.next = null;
        return temp;
    }


    public static void main(String[] args)
    {

        Node head = newNode(1);
        head.next = newNode(2);
        head.next.next = newNode(6);
        head.next.next.next = newNode(13);

        System.out.println("Given Linked List");
        printList(head);

        head = deleteMid(head);

        System.out.println("Linked List after deletion of middle");
        printList(head);
    }
}

Output

Given Linked List
1→2→6→13→NULL
Linked List after deletion of middle
1→2→13→NULL

Time Complexity: O(n), as list traversal is needed.

So, in this article, we have tried to explain the most efficient approach to delete the middle of a linked list. This is an important problem when it comes to coding interviews. If you want to solve more questions on Linked List, which are curated by our expert mentors at PrepBytes, you can follow this link Linked List.

Previous post Intersection point of two linked lists
Next post Delete nodes that have a greater value on the right side

Leave a Reply

Your email address will not be published. Required fields are marked *