Reverse a sublist of linked list (original) (raw)
Last Updated : 27 Aug, 2024
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
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
// 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
// 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
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 prevNodedef 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 headdef 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#
// 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);
}}
JavaScript
// 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++ `
// 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
// 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
// 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);
}}
Python
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 headdef 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#
// 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
// 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).
