Open In App

Reverse a sublist of linked list

Last Updated : 27 Aug, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

Given a linked list and positions m and n. We need to reverse the linked list from position m to n.

Examples:  

Input : linkedlist : 10->20->30->40->50->60->70->NULL , m = 3 and n = 6
Output : 10->20->60->50->40->30->70->NULL
Explanation: Linkedlist reversed starting from the node m i.e. 30 and n i.e. 60

Reverse-a-sublist-of-linked-list

Example of Reverse a sublist of linked list


Input : linkedlist : 1->2->3->4->5->6->NULL , m = 2 and n = 4
Output : 1->4->3->2->5->6->NULL
Explanation: Linkedlist reversed starting from the node m i.e. 2 and n i.e. 4

[Expected Approach – 1] Using Two Traversal – O(n) time and O(1) Space:

The idea is to reverse a segment of the linked list by locating the start and end nodes, removing the links and reversing the segment using standard reverse function, and then reattaching it back to the main list.

Step-by-step approach :

  • Find the start and end positions of the linked list by running a loop.
  • Unlink the portion of the list that needs to be reversed from the rest of the list.
  • Reverse the unlinked portion using the standard linked list reverse function.
  • Reattach the reversed portion to the main list.

Below is the implementation of above approach:

C++
// C++ program to reverse a linked list
// from position m to position n
#include <bits/stdc++.h>
using namespace std;

struct Node {
    int data;
    struct Node *next;
    Node(int val) {
        data = val;
        next = nullptr;
    }
};

// Function to reverse a linked list
Node *reverse(struct Node *head) {
    Node *prevNode = NULL;
    Node *currNode = head;
    while (currNode) {
        Node *nextNode = currNode->next;
        currNode->next = prevNode;
        prevNode = currNode;
        currNode = nextNode;
    }
    return prevNode;
}

// Function to reverse a linked list from position m to n
Node *reverseBetween(Node *head, int m, int n) {
  
    // If m and n are the same, no reversal is needed
    if (m == n)
        return head;

    Node *revs = NULL, *revs_prev = NULL;
    Node *revend = NULL, *revend_next = NULL;

    // Traverse the list to locate the nodes
    // and pointers needed for reversal
    int i = 1;
    Node *currNode = head;
    while (currNode && i <= n) {

        // Track the node just before the start of
        // the reversal segment
        if (i < m)
            revs_prev = currNode;
      
        // Track the start of the reversal segment
        if (i == m)
            revs = currNode;
      
        // Track the end of the reversal
        // segment and the node right after it
        if (i == n) {
            revend = currNode;
            revend_next = currNode->next;
        }
        currNode = currNode->next;
        i++;
    }

    // Detach the segment to be reversed
    // from the rest of the list
    revend->next = NULL;

    // Reverse the segment from position m to n
    revend = reverse(revs);

    // Reattach the reversed segment back to the list
    // If the reversal segment was not at the head of the list
    if (revs_prev)
        revs_prev->next = revend;
    else
        head = revend;

    // Connect the end of the reversed
    // segment to the rest of the list
    revs->next = revend_next;

    return head;
}

void print(Node *head) {
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << "NULL" << endl;
}

int main() {
  
    // Initialize linked list:
    // 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
    Node *head = new Node(10);
    head->next = new Node(20);
    head->next->next = new Node(30);
    head->next->next->next = new Node(40);
    head->next->next->next->next = new Node(50);
    head->next->next->next->next->next = new Node(60);
    head->next->next->next->next->next->next = new Node(70);

    cout << "Original list: ";
    print(head);
  
    head = reverseBetween(head, 3, 6);

    cout << "Modified list: ";
    print(head);

    return 0;
}
C Java Python C# JavaScript

Output
Original list: 10 20 30 40 50 60 70 NULL
Modified list: 10 20 60 50 40 30 70 NULL

Time Complexity: O(n), Here n is the number of nodes in the linked list. In the worst case we need to traverse the list twice.
Auxiliary Space: O(1).

[Expected Approach – 2] Using Single Traversal – O(n) time and O(1) Space:

The idea is to get pointers to the head and tail of the reversed segment, the node before the mth node, and the node after the nth node and then reverse the segment and reconnect the links appropriately.

Follow the steps below to solve the problem:

  • Get the pointer to the head and tail of the reversed linked list.
  • Get the pointer to the node before mth and node after nth node.
  • Reverse the list using standard linked list reverse function.
  • Connect back the links properly.

Step-by-step approach :

C++
// C++ program to reverse a linked list
// from position m to position n
#include <bits/stdc++.h>
using namespace std;

struct Node {
    int data;
    struct Node *next;

    Node(int val) {
        data = val;
        next = nullptr;
    }
};

// Function used to reverse a linked list 
// from position m to n
Node *reverseBetween(Node *head, int m, int n) {
    Node *currNode = head, *prevNode = NULL;
    int i;

    // Move currNode to the position m
    for (i = 1; i < m; i++) {
        prevNode = currNode;
        currNode = currNode->next;
    }

    // Store pointers to the start and 
      // end of the reversed segment
    Node *revHead = currNode;
    Node *revTail = NULL;

    // Reverse the linked list from position m to n
    Node *nextNode = NULL;
    while (i <= n) {
        nextNode = currNode->next;
        currNode->next = revTail;
        revTail = currNode;
        currNode = nextNode;
        i++;
    }

    // Connect the reversed segment back to the list
    if (prevNode != NULL)
        prevNode->next = revTail;

    else
        head = revTail;

    revHead->next = currNode;

    return head;
}

void print(struct Node *head) {
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << "NULL" << endl;
}

int main() {
  
    // Initialize linked list:
    // 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
    Node *head = new Node(10);
    head->next = new Node(20);
    head->next->next = new Node(30);
    head->next->next->next = new Node(40);
    head->next->next->next->next = new Node(50);
    head->next->next->next->next->next = new Node(60);
    head->next->next->next->next->next->next = new Node(70);

    cout << "Original list: ";
    print(head);

    head = reverseBetween(head, 3, 6);

    cout << "Modified list: ";
    print(head);

    return 0;
}
C Java Python C# JavaScript

Output
Original list: 10 20 30 40 50 60 70 NULL
Modified list: 10 20 60 50 40 30 70 NULL

Time Complexity: O(n) ,where n the size of the linked list.
Auxiliary Space: O(1).

 



Next Article
Article Tags :
Practice Tags :

Similar Reads

three90RightbarBannerImg