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 mi.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 mi.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>usingnamespacestd;structNode{intdata;structNode*next;Node(intval){data=val;next=nullptr;}};// Function to reverse a linked listNode*reverse(structNode*head){Node*prevNode=NULL;Node*currNode=head;while(currNode){Node*nextNode=currNode->next;currNode->next=prevNode;prevNode=currNode;currNode=nextNode;}returnprevNode;}// Function to reverse a linked list from position m to nNode*reverseBetween(Node*head,intm,intn){// If m and n are the same, no reversal is neededif(m==n)returnhead;Node*revs=NULL,*revs_prev=NULL;Node*revend=NULL,*revend_next=NULL;// Traverse the list to locate the nodes// and pointers needed for reversalinti=1;Node*currNode=head;while(currNode&&i<=n){// Track the node just before the start of// the reversal segmentif(i<m)revs_prev=currNode;// Track the start of the reversal segmentif(i==m)revs=currNode;// Track the end of the reversal// segment and the node right after itif(i==n){revend=currNode;revend_next=currNode->next;}currNode=currNode->next;i++;}// Detach the segment to be reversed// from the rest of the listrevend->next=NULL;// Reverse the segment from position m to nrevend=reverse(revs);// Reattach the reversed segment back to the list// If the reversal segment was not at the head of the listif(revs_prev)revs_prev->next=revend;elsehead=revend;// Connect the end of the reversed// segment to the rest of the listrevs->next=revend_next;returnhead;}voidprint(Node*head){while(head!=NULL){cout<<head->data<<" ";head=head->next;}cout<<"NULL"<<endl;}intmain(){// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70Node*head=newNode(10);head->next=newNode(20);head->next->next=newNode(30);head->next->next->next=newNode(40);head->next->next->next->next=newNode(50);head->next->next->next->next->next=newNode(60);head->next->next->next->next->next->next=newNode(70);cout<<"Original list: ";print(head);head=reverseBetween(head,3,6);cout<<"Modified list: ";print(head);return0;}
C
// C program to reverse a linked list// from position m to position n#include<stdio.h>structNode{intdata;structNode*next;};// Function to reverse a linked liststructNode*reverse(structNode*head){structNode*prevNode=NULL;structNode*currNode=head;while(currNode){structNode*nextNode=currNode->next;currNode->next=prevNode;prevNode=currNode;currNode=nextNode;}returnprevNode;}// Function to reverse a linked list// from position m to nstructNode*reverseBetween(structNode*head,intm,intn){// If m and n are the same, no reversal is neededif(m==n)returnhead;structNode*revs=NULL,*revs_prev=NULL;structNode*revend=NULL,*revend_next=NULL;// Traverse the list to locate the nodes// and pointers needed for reversalinti=1;structNode*currNode=head;while(currNode&&i<=n){// Track the node just before the start// of the reversal segmentif(i<m)revs_prev=currNode;// Track the start of the reversal segmentif(i==m)revs=currNode;// Track the end of the reversal// segment and the node right after itif(i==n){revend=currNode;revend_next=currNode->next;}currNode=currNode->next;i++;}// Detach the segment to be reversed from // the rest of the listrevend->next=NULL;// Reverse the segment from position m to nrevend=reverse(revs);// Reattach the reversed segment back to the list// If the reversal segment was not at the head of the listif(revs_prev)revs_prev->next=revend;elsehead=revend;// Connect the end of the reversed// segment to the rest of the listrevs->next=revend_next;returnhead;}voidprint(structNode*head){while(head!=NULL){printf("%d ",head->data);head=head->next;}printf("NULL\n");}structNode*createNode(intnew_data){structNode*new_node=(structNode*)malloc(sizeof(structNode));new_node->data=new_data;new_node->next=NULL;returnnew_node;}intmain(){// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70structNode*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);return0;}
Java
// Java program to reverse a linked list// from position m to position nclassNode{intdata;Nodenext;Node(intnew_data){data=new_data;next=null;}}publicclassGfG{// Function to reverse a linked liststaticNodereverse(Nodehead){NodeprevNode=null;NodecurrNode=head;while(currNode!=null){NodenextNode=currNode.next;currNode.next=prevNode;prevNode=currNode;currNode=nextNode;}returnprevNode;}// Function to reverse a linked list from position m to nstaticNodereverseBetween(Nodehead,intm,intn){// If m and n are the same, no reversal is neededif(m==n)returnhead;Noderevs=null,revs_prev=null;Noderevend=null,revend_next=null;// Traverse the list to locate the nodes // and pointers needed for reversalinti=1;NodecurrNode=head;while(currNode!=null&&i<=n){// Track the node just before the start of //the reversal segmentif(i<m)revs_prev=currNode;// Track the start of the reversal segmentif(i==m)revs=currNode;// Track the end of the reversal // segment and the node right after itif(i==n){revend=currNode;revend_next=currNode.next;}currNode=currNode.next;i++;}// Detach the segment to be reversed // from the rest of the listif(revs!=null)revend.next=null;// Reverse the segment from position m to nrevend=reverse(revs);// Reattach the reversed segment back to the list// If the reversal segment was not at the head of the listif(revs_prev!=null)revs_prev.next=revend;elsehead=revend;// Connect the end of the reversed // segment to the rest of the listif(revs!=null)revs.next=revend_next;returnhead;}staticvoidprint(Nodehead){while(head!=null){System.out.print(head.data+" ");head=head.next;}System.out.println("NULL");}publicstaticvoidmain(String[]args){// Initialize linked list: // 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70Nodehead=newNode(10);head.next=newNode(20);head.next.next=newNode(30);head.next.next.next=newNode(40);head.next.next.next.next=newNode(50);head.next.next.next.next.next=newNode(60);head.next.next.next.next.next.next=newNode(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 nclassNode:def__init__(self,val):self.data=valself.next=Nonedefreverse(head):# Function to reverse a linked listprevNode=NonecurrNode=headwhilecurrNode:nextNode=currNode.nextcurrNode.next=prevNodeprevNode=currNodecurrNode=nextNodereturnprevNodedefreverse_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 neededifm==n:returnheadrevs=Nonerevs_prev=Nonerevend=Nonerevend_next=None# Traverse the list to locate the nodes# and pointers needed for reversali=1currNode=headwhilecurrNodeandi<=n:# Track the node just before the start# of the reversal segmentifi<m:revs_prev=currNode# Track the start of the reversal segmentifi==m:revs=currNode# Track the end of the reversal segment and# the node right after itifi==n:revend=currNoderevend_next=currNode.nextcurrNode=currNode.nexti+=1# Detach the segment to be reversed from the rest# of the listifrevend:revend.next=None# Reverse the segment from position m to nrevend=reverse(revs)# Reattach the reversed segment back to the list# If the reversal segment was not at the head of the listifrevs_prev:revs_prev.next=revendelse:head=revend# Connect the end of the reversed segment to# the rest of the listifrevs:revs.next=revend_nextreturnheaddefprint_list(head):whilehead:print(head.data,end=" ")head=head.nextprint("NULL")if__name__=="__main__":# Initialize linked list:# 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70head=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 nusingSystem;publicclassNode{publicintData;publicNodeNext;publicNode(intnewData){Data=newData;Next=null;}}classGfG{// Function to reverse a linked liststaticNodeReverse(Nodehead){NodeprevNode=null;NodecurrNode=head;while(currNode!=null){NodenextNode=currNode.Next;currNode.Next=prevNode;prevNode=currNode;currNode=nextNode;}returnprevNode;}// Function to reverse a linked list from position m to// nstaticNodeReverseBetween(Nodehead,intm,intn){// If m and n are the same, no reversal is neededif(m==n)returnhead;Noderevs=null,revsPrev=null;Noderevend=null,revendNext=null;// Traverse the list to locate the nodes// and pointers needed for reversalinti=1;NodecurrNode=head;while(currNode!=null&&i<=n){// Track the node just before the start// of the reversal segmentif(i<m)revsPrev=currNode;// Track the start of the reversal segmentif(i==m)revs=currNode;// Track the end of the reversal// segment and the node right after itif(i==n){revend=currNode;revendNext=currNode.Next;}currNode=currNode.Next;i++;}// Detach the segment to be reversed// from the rest of the listif(revs!=null)revend.Next=null;// Reverse the segment from position m to nrevend=Reverse(revs);// Reattach the reversed segment back to the list// If the reversal segment was not at the head of// the listif(revsPrev!=null)revsPrev.Next=revend;elsehead=revend;// Connect the end of the reversed// segment to the rest of the listif(revs!=null)revs.Next=revendNext;returnhead;}staticvoidPrint(Nodehead){while(head!=null){Console.Write(head.Data+" ");head=head.Next;}Console.WriteLine("NULL");}staticvoidMain(string[]args){// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70Nodehead=newNode(10);head.Next=newNode(20);head.Next.Next=newNode(30);head.Next.Next.Next=newNode(40);head.Next.Next.Next.Next=newNode(50);head.Next.Next.Next.Next.Next=newNode(60);head.Next.Next.Next.Next.Next.Next=newNode(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 nclassNode{constructor(val){this.data=val;this.next=null;}}// Function to reverse a linked listfunctionreverse(head){letprevNode=null;letcurrNode=head;while(currNode){letnextNode=currNode.next;currNode.next=prevNode;prevNode=currNode;currNode=nextNode;}returnprevNode;}// Function to reverse a linked list// from position m to nfunctionreverseBetween(head,m,n){// If m and n are the same, no reversal is neededif(m===n)returnhead;letrevs=null,revs_prev=null;letrevend=null,revend_next=null;// Traverse the list to locate the nodes// and pointers needed for reversalleti=1;letcurrNode=head;while(currNode&&i<=n){// Track the node just before the start of the// reversal segmentif(i<m)revs_prev=currNode;// Track the start of the reversal segmentif(i===m)revs=currNode;// Track the end of the reversal segment and the// node right after itif(i===n){revend=currNode;revend_next=currNode.next;}currNode=currNode.next;i++;}// Detach the segment to be reversed from the rest of// the listif(revend)revend.next=null;// Reverse the segment from position m to nrevend=reverse(revs);// Reattach the reversed segment back to the list// If the reversal segment was not at the head of the// listif(revs_prev)revs_prev.next=revend;elsehead=revend;// Connect the end of the reversed segment to the rest// of the listif(revs)revs.next=revend_next;returnhead;}functionprint(head){while(head!==null){process.stdout.write(head.data+" ");head=head.next;}console.log("NULL");}// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70lethead=newNode(10);head.next=newNode(20);head.next.next=newNode(30);head.next.next.next=newNode(40);head.next.next.next.next=newNode(50);head.next.next.next.next.next=newNode(60);head.next.next.next.next.next.next=newNode(70);console.log("Original list: ");print(head);head=reverseBetween(head,3,6);console.log("Modified list: ");print(head);
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>usingnamespacestd;structNode{intdata;structNode*next;Node(intval){data=val;next=nullptr;}};// Function used to reverse a linked list // from position m to nNode*reverseBetween(Node*head,intm,intn){Node*currNode=head,*prevNode=NULL;inti;// Move currNode to the position mfor(i=1;i<m;i++){prevNode=currNode;currNode=currNode->next;}// Store pointers to the start and // end of the reversed segmentNode*revHead=currNode;Node*revTail=NULL;// Reverse the linked list from position m to nNode*nextNode=NULL;while(i<=n){nextNode=currNode->next;currNode->next=revTail;revTail=currNode;currNode=nextNode;i++;}// Connect the reversed segment back to the listif(prevNode!=NULL)prevNode->next=revTail;elsehead=revTail;revHead->next=currNode;returnhead;}voidprint(structNode*head){while(head!=NULL){cout<<head->data<<" ";head=head->next;}cout<<"NULL"<<endl;}intmain(){// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70Node*head=newNode(10);head->next=newNode(20);head->next->next=newNode(30);head->next->next->next=newNode(40);head->next->next->next->next=newNode(50);head->next->next->next->next->next=newNode(60);head->next->next->next->next->next->next=newNode(70);cout<<"Original list: ";print(head);head=reverseBetween(head,3,6);cout<<"Modified list: ";print(head);return0;}
C
// C program to reverse a linked list// from position m to position n#include<stdio.h>#include<stdlib.h>structNode{intdata;structNode*next;};// Function used to reverse a linked list // from position m to nstructNode*reverseBetween(structNode*head,intm,intn){structNode*currNode=head;structNode*prevNode=NULL;inti;// Move currNode to the position mfor(i=1;i<m;i++){prevNode=currNode;currNode=currNode->next;}// Store pointers to the start and // end of the reversed segmentstructNode*revHead=currNode;structNode*revTail=NULL;// Reverse the linked list from position m to nstructNode*nextNode=NULL;while(i<=n){nextNode=currNode->next;currNode->next=revTail;revTail=currNode;currNode=nextNode;i++;}// Connect the reversed segment back to the listif(prevNode!=NULL)prevNode->next=revTail;elsehead=revTail;revHead->next=currNode;returnhead;}voidprint(structNode*head){while(head!=NULL){printf("%d ",head->data);head=head->next;}printf("NULL\n");}structNode*createNode(intnew_data){structNode*new_node=(structNode*)malloc(sizeof(structNode));new_node->data=new_data;new_node->next=NULL;returnnew_node;}intmain(){// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70structNode*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);return0;}
Java
// Java program to reverse a linked list// from position m to position nclassNode{intdata;Nodenext;publicNode(intval){data=val;next=null;}}publicclassGfG{// Function used to reverse a linked list from position// m to nstaticNodereverseBetween(Nodehead,intm,intn){NodecurrNode=head,prevNode=null;inti;// Move currNode to the position mfor(i=1;i<m;i++){prevNode=currNode;currNode=currNode.next;}// Store pointers to the start// and end of the reversed segmentNoderevHead=currNode;NoderevTail=null;// Reverse the linked list from position m to nNodenextNode;while(i<=n){nextNode=currNode.next;currNode.next=revTail;revTail=currNode;currNode=nextNode;i++;}// Connect the reversed segment back to the listif(prevNode!=null){prevNode.next=revTail;}else{head=revTail;}revHead.next=currNode;returnhead;}publicstaticvoidprint(Nodehead){while(head!=null){System.out.print(head.data+" ");head=head.next;}System.out.println("NULL");}publicstaticvoidmain(String[]args){// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70Nodehead=newNode(10);head.next=newNode(20);head.next.next=newNode(30);head.next.next.next=newNode(40);head.next.next.next.next=newNode(50);head.next.next.next.next.next=newNode(60);head.next.next.next.next.next.next=newNode(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 nclassNode:def__init__(self,val):self.data=valself.next=Nonedefreverse_between(head,m,n):currNode=headprevNode=Nonei=1# Move currNode to the position mwhilei<m:prevNode=currNodecurrNode=currNode.nexti+=1# Store pointers to the start and end# of the reversed segmentrevHead=currNoderevTail=None# Reverse the linked list from position m to nwhilei<=n:nextNode=currNode.nextcurrNode.next=revTailrevTail=currNodecurrNode=nextNodei+=1# Connect the reversed segment back to the listifprevNodeisnotNone:prevNode.next=revTailelse:head=revTailrevHead.next=currNodereturnheaddefprint_list(head):whileheadisnotNone:print(head.data,end=" ")head=head.nextprint("NULL")if__name__=="__main__":# Initialize linked list:# 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70head=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 nusingSystem;classNode{publicintData;publicNodeNext;publicNode(intnewData){Data=newData;Next=null;}}classGfG{// Function used to reverse a// linked list from position m to nstaticNodeReverseBetween(Nodehead,intm,intn){NodecurrNode=head,prevNode=null;inti;// Move currNode to the position mfor(i=1;i<m;i++){prevNode=currNode;currNode=currNode.Next;}// Store pointers to the start and end// of the reversed segmentNoderevHead=currNode;NoderevTail=null;// Reverse the linked list from position m to nNodenextNode;while(i<=n){nextNode=currNode.Next;currNode.Next=revTail;revTail=currNode;currNode=nextNode;i++;}// Connect the reversed segment back to the listif(prevNode!=null){prevNode.Next=revTail;}else{head=revTail;}revHead.Next=currNode;returnhead;}staticvoidPrint(Nodehead){while(head!=null){Console.Write(head.Data+" ");head=head.Next;}Console.WriteLine("NULL");}staticvoidMain(){// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70Nodehead=newNode(10);head.Next=newNode(20);head.Next.Next=newNode(30);head.Next.Next.Next=newNode(40);head.Next.Next.Next.Next=newNode(50);head.Next.Next.Next.Next.Next=newNode(60);head.Next.Next.Next.Next.Next.Next=newNode(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 nclassNode{constructor(val){this.data=val;this.next=null;}}functionreverseBetween(head,m,n){letcurrNode=head;letprevNode=null;leti;// Move currNode to the position mfor(i=1;i<m;i++){prevNode=currNode;currNode=currNode.next;}// Store pointers to the start and end // of the reversed segmentletrevHead=currNode;letrevTail=null;// Reverse the linked list from position m to nletnextNode=null;while(i<=n){nextNode=currNode.next;currNode.next=revTail;revTail=currNode;currNode=nextNode;i++;}// Connect the reversed segment back to the listif(prevNode!==null){prevNode.next=revTail;}else{head=revTail;}revHead.next=currNode;returnhead;}functionprint(head){letcurrNode=head;while(currNode!==null){process.stdout.write(currNode.data+" ");currNode=currNode.next;}console.log("NULL");}// Initialize linked list:// 10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70lethead=newNode(10);head.next=newNode(20);head.next.next=newNode(30);head.next.next.next=newNode(40);head.next.next.next.next=newNode(50);head.next.next.next.next.next=newNode(60);head.next.next.next.next.next.next=newNode(70);console.log("Original list: ");print(head);head=reverseBetween(head,3,6);console.log("Modified list: ");print(head);