Reverse a sublist of linked list
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. 60Example 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++ 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 program to reverse a linked list
// from position m to position n
#include <stdio.h>
struct Node {
int data;
struct Node *next;
};
// Function to reverse a linked list
struct Node *reverse(struct Node *head) {
struct Node *prevNode = NULL;
struct Node *currNode = head;
while (currNode) {
struct Node *nextNode = currNode->next;
currNode->next = prevNode;
prevNode = currNode;
currNode = nextNode;
}
return prevNode;
}
// Function to reverse a linked list
// from position m to n
struct Node *reverseBetween(struct Node *head, int m, int n) {
// If m and n are the same, no reversal is needed
if (m == n)
return head;
struct Node *revs = NULL, *revs_prev = NULL;
struct Node *revend = NULL, *revend_next = NULL;
// Traverse the list to locate the nodes
// and pointers needed for reversal
int i = 1;
struct 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(struct Node *head) {
while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
printf("NULL\n");
}
struct Node *createNode(int new_data) {
struct Node *new_node =
(struct Node *)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = NULL;
return new_node;
}
int main() {
// Initialize linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
struct Node *head = createNode(10);
head->next = createNode(20);
head->next->next = createNode(30);
head->next->next->next = createNode(40);
head->next->next->next->next = createNode(50);
head->next->next->next->next->next = createNode(60);
head->next->next->next->next->next->next = createNode(70);
printf("Original list: ");
print(head);
head = reverseBetween(head, 3, 6);
printf("Modified list: ");
print(head);
return 0;
}
// Java program to reverse a linked list
// from position m to position n
class Node {
int data;
Node next;
Node(int new_data) {
data = new_data;
next = null;
}
}
public class GfG {
// Function to reverse a linked list
static Node reverse(Node head) {
Node prevNode = null;
Node currNode = head;
while (currNode != null) {
Node nextNode = currNode.next;
currNode.next = prevNode;
prevNode = currNode;
currNode = nextNode;
}
return prevNode;
}
// Function to reverse a linked list from position m to n
static 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 != null && 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
if (revs != null) 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 != null)
revs_prev.next = revend;
else
head = revend;
// Connect the end of the reversed
// segment to the rest of the list
if (revs != null) revs.next = revend_next;
return head;
}
static void print(Node head) {
while (head != null) {
System.out.print(head.data + " ");
head = head.next;
}
System.out.println("NULL");
}
public static void main(String[] args) {
// 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);
System.out.print("Original list: ");
print(head);
head = reverseBetween(head, 3, 6);
System.out.print("Modified list: ");
print(head);
}
}
# Python program to reverse a linked list
# from position m to position n
class Node:
def __init__(self, val):
self.data = val
self.next = None
def reverse(head):
# Function to reverse a linked list
prevNode = None
currNode = head
while currNode:
nextNode = currNode.next
currNode.next = prevNode
prevNode = currNode
currNode = nextNode
return prevNode
def reverse_between(head, m, n):
# Function to reverse a linked list from position m to n
# If m and n are the same, no reversal is needed
if m == n:
return head
revs = None
revs_prev = None
revend = None
revend_next = None
# Traverse the list to locate the nodes
# and pointers needed for reversal
i = 1
currNode = head
while currNode and 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 += 1
# Detach the segment to be reversed from the rest
# of the list
if revend:
revend.next = None
# 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
if revs:
revs.next = revend_next
return head
def print_list(head):
while head:
print(head.data, end=" ")
head = head.next
print("NULL")
if __name__ == "__main__":
# Initialize linked list:
# 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head.next.next.next = Node(40)
head.next.next.next.next = Node(50)
head.next.next.next.next.next = Node(60)
head.next.next.next.next.next.next = Node(70)
print("Original list: ", end="")
print_list(head)
head = reverse_between(head, 3, 6)
print("Modified list: ", end="")
print_list(head)
// C# program to reverse a linked list
// from position m to position n
using System;
public class Node {
public int Data;
public Node Next;
public Node(int newData) {
Data = newData;
Next = null;
}
}
class GfG {
// Function to reverse a linked list
static Node Reverse(Node head) {
Node prevNode = null;
Node currNode = head;
while (currNode != null) {
Node nextNode = currNode.Next;
currNode.Next = prevNode;
prevNode = currNode;
currNode = nextNode;
}
return prevNode;
}
// Function to reverse a linked list from position m to
// n
static 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, revsPrev = null;
Node revend = null, revendNext = null;
// Traverse the list to locate the nodes
// and pointers needed for reversal
int i = 1;
Node currNode = head;
while (currNode != null && i <= n) {
// Track the node just before the start
// of the reversal segment
if (i < m)
revsPrev = 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;
revendNext = currNode.Next;
}
currNode = currNode.Next;
i++;
}
// Detach the segment to be reversed
// from the rest of the list
if (revs != null)
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 (revsPrev != null)
revsPrev.Next = revend;
else
head = revend;
// Connect the end of the reversed
// segment to the rest of the list
if (revs != null)
revs.Next = revendNext;
return head;
}
static void Print(Node head) {
while (head != null) {
Console.Write(head.Data + " ");
head = head.Next;
}
Console.WriteLine("NULL");
}
static void Main(string[] args) {
// 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);
Console.Write("Original list: ");
Print(head);
head = ReverseBetween(head, 3, 6);
Console.Write("Modified list: ");
Print(head);
}
}
// JavaScipt program to reverse a linked list
// from position m to position n
class Node {
constructor(val) {
this.data = val;
this.next = null;
}
}
// Function to reverse a linked list
function reverse(head) {
let prevNode = null;
let currNode = head;
while (currNode) {
let nextNode = currNode.next;
currNode.next = prevNode;
prevNode = currNode;
currNode = nextNode;
}
return prevNode;
}
// Function to reverse a linked list
// from position m to n
function reverseBetween(head, m, n) {
// If m and n are the same, no reversal is needed
if (m === n)
return head;
let revs = null, revs_prev = null;
let revend = null, revend_next = null;
// Traverse the list to locate the nodes
// and pointers needed for reversal
let i = 1;
let 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
if (revend)
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
if (revs)
revs.next = revend_next;
return head;
}
function print(head) {
while (head !== null) {
process.stdout.write(head.data + " ");
head = head.next;
}
console.log("NULL");
}
// Initialize linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
let 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);
console.log("Original list: ");
print(head);
head = reverseBetween(head, 3, 6);
console.log("Modified list: ");
print(head);
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++ 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 program to reverse a linked list
// from position m to position n
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
// Function used to reverse a linked list
// from position m to n
struct Node *reverseBetween(struct Node *head, int m, int n) {
struct Node *currNode = head;
struct Node *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
struct Node *revHead = currNode;
struct Node *revTail = NULL;
// Reverse the linked list from position m to n
struct 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) {
printf("%d ", head->data);
head = head->next;
}
printf("NULL\n");
}
struct Node *createNode(int new_data) {
struct Node *new_node =
(struct Node *)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = NULL;
return new_node;
}
int main() {
// Initialize linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
struct Node *head = createNode(10);
head->next = createNode(20);
head->next->next = createNode(30);
head->next->next->next = createNode(40);
head->next->next->next->next = createNode(50);
head->next->next->next->next->next = createNode(60);
head->next->next->next->next->next->next = createNode(70);
printf("Original list: ");
print(head);
head = reverseBetween(head, 3, 6);
printf("Modified list: ");
print(head);
return 0;
}
// Java program to reverse a linked list
// from position m to position n
class Node {
int data;
Node next;
public Node(int val) {
data = val;
next = null;
}
}
public class GfG {
// Function used to reverse a linked list from position
// m to n
static 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;
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;
}
public static void print(Node head) {
while (head != null) {
System.out.print(head.data + " ");
head = head.next;
}
System.out.println("NULL");
}
public static void main(String[] args) {
// 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);
System.out.print("Original list: ");
print(head);
head = reverseBetween(head, 3, 6);
System.out.print("Modified list: ");
print(head);
}
}
# Python3 program to reverse a linked list
# from position m to position n
class Node:
def __init__(self, val):
self.data = val
self.next = None
def reverse_between(head, m, n):
currNode = head
prevNode = None
i = 1
# Move currNode to the position m
while i < m:
prevNode = currNode
currNode = currNode.next
i += 1
# Store pointers to the start and end
# of the reversed segment
revHead = currNode
revTail = None
# Reverse the linked list from position m to n
while i <= n:
nextNode = currNode.next
currNode.next = revTail
revTail = currNode
currNode = nextNode
i += 1
# Connect the reversed segment back to the list
if prevNode is not None:
prevNode.next = revTail
else:
head = revTail
revHead.next = currNode
return head
def print_list(head):
while head is not None:
print(head.data, end=" ")
head = head.next
print("NULL")
if __name__ == "__main__":
# Initialize linked list:
# 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head.next.next.next = Node(40)
head.next.next.next.next = Node(50)
head.next.next.next.next.next = Node(60)
head.next.next.next.next.next.next = Node(70)
print("Original list: ", end="")
print_list(head)
head = reverse_between(head, 3, 6)
print("Modified list: ", end="")
print_list(head)
// C# program to reverse a linked list
// from position m to position n
using System;
class Node {
public int Data;
public Node Next;
public Node(int newData) {
Data = newData;
Next = null;
}
}
class GfG {
// Function used to reverse a
// linked list from position m to n
static 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;
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;
}
static void Print(Node head) {
while (head != null) {
Console.Write(head.Data + " ");
head = head.Next;
}
Console.WriteLine("NULL");
}
static void 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);
Console.Write("Original list: ");
Print(head);
head = ReverseBetween(head, 3, 6);
Console.Write("Modified list: ");
Print(head);
}
}
// JavaScript program to reverse a linked
// list from position m to position n
class Node {
constructor(val) {
this.data = val;
this.next = null;
}
}
function reverseBetween(head, m, n) {
let currNode = head;
let prevNode = null;
let 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
let revHead = currNode;
let revTail = null;
// Reverse the linked list from position m to n
let 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;
}
function print(head) {
let currNode = head;
while (currNode !== null) {
process.stdout.write(currNode.data + " ");
currNode = currNode.next;
}
console.log("NULL");
}
// Initialize linked list:
// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70
let 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);
console.log("Original list: ");
print(head);
head = reverseBetween(head, 3, 6);
console.log("Modified list: ");
print(head);
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).