Given the head of a Doubly Linked List, reverse the list in-place so that the first node becomes the last, the second node becomes the second last, and so on. Return the new head of the reversed list.
Examples:
Input:
Output: 3 <-> 2 <-> 1 -> NULL
Input:
Output: 1 ->NULL Explanation: Reverse of single node is same.
[Naive Approach] Using Recursion - O(n) Time and O(n) Space
The idea is to reverse the doubly linked list by swapping the next and prev pointers of each node. Once the pointers of the current node are swapped, we make a recursive call on the new prev pointer (which originally was the next node) to process the rest of the list.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*next,*prev;Node(intval){data=val;next=nullptr;prev=nullptr;}};Node*reverse(Node*curr){// Base case: if the list is empty or we// reach the end of the listif(curr==nullptr)returnnullptr;swap(curr->prev,curr->next);// If the previous node (after swap) is null,// this is the new headif(curr->prev==nullptr)returncurr;returnreverse(curr->prev);}voidprintList(Node*node){while(node!=nullptr){cout<<node->data;if(node->next!=nullptr){cout<<" <-> ";}node=node->next;}}intmain(){Node*head=newNode(1);head->next=newNode(2);head->next->prev=head;head->next->next=newNode(3);head->next->next->prev=head->next;head=reverse(head);printList(head);return0;}
C
#include<stdio.h>structNode{intdata;structNode*next;structNode*prev;};structNode*reverse(structNode*curr){// Base case: If the list is empty or we// reach the end of the listif(curr==NULL)returnNULL;// Swap the next and prev pointersstructNode*temp=curr->prev;curr->prev=curr->next;curr->next=temp;// If the previous node (after swap) is NULL// his is the new headif(curr->prev==NULL)returncurr;returnreverse(curr->prev);}voidprintList(structNode*node){while(node!=NULL){printf("%d ",node->data);if(node->next!=NULL){printf("<-> ");}node=node->next;}printf("\n");}structNode*createNode(intnew_data){structNode*new_node=(structNode*)malloc(sizeof(structNode));new_node->data=new_data;new_node->next=NULL;new_node->prev=NULL;returnnew_node;}intmain(){structNode*head=createNode(1);head->next=createNode(2);head->next->prev=head;head->next->next=createNode(3);head->next->next->prev=head->next;head=reverse(head);printList(head);return0;}
Java
classGfG{staticNodehead;staticclassNode{intdata;Nodenext,prev;Node(intd){data=d;next=prev=null;}}staticNodereverse(Nodecurr){// Base case: If list is empty or we // reach the end of the listif(curr==null)returnnull;// Swap the next and prev pointersNodetemp=curr.prev;curr.prev=curr.next;curr.next=temp;// If prev is null after swap, this is the new headif(curr.prev==null){returncurr;}returnreverse(curr.prev);}staticvoidprintList(Nodenode){while(node!=null){System.out.print(node.data);if(node.next!=null){System.out.print(" <-> ");}node=node.next;}System.out.println();}publicstaticvoidmain(String[]args){head=newNode(1);head.next=newNode(2);head.next.prev=head;head.next.next=newNode(3);head.next.next.prev=head.next;head=reverse(head);printList(head);}}
Python
classNode:def__init__(self,val):self.data=valself.next=Noneself.prev=Nonedefreverse(curr):# Base case: if the list is# empty or we reach the end of the listifcurrisNone:returnNone# Swap the next and prev pointerstemp=curr.prevcurr.prev=curr.nextcurr.next=tempifcurr.previsNone:returncurrreturnreverse(curr.prev)defprintList(node):whilenodeisnotNone:print(node.data,end="")ifnode.nextisnotNone:print(" <-> ",end="")node=node.nextprint()if__name__=="__main__":head=Node(1)head.next=Node(2)head.next.prev=headhead.next.next=Node(3)head.next.next.prev=head.nexthead=reverse(head)printList(head)
C#
usingSystem;publicclassNode{publicintData;publicNodenext;publicNodePrev;publicNode(intval){Data=val;next=null;Prev=null;}}classGfG{staticNodereverse(Nodecurr){// Base case: if the list is empty or we reach the// end of the listif(curr==null)returnnull;// Swap the next and prev pointersNodetemp=curr.Prev;curr.Prev=curr.next;curr.next=temp;// If the previous node (after swap) is null, // this is the new headif(curr.Prev==null)returncurr;returnreverse(curr.Prev);}staticvoidprintList(Nodenode){while(node!=null){Console.Write(node.Data);if(node.next!=null){Console.Write(" <-> ");}node=node.next;}Console.WriteLine();}staticvoidMain(){Nodehead=newNode(1);head.next=newNode(2);head.next.Prev=head;head.next.next=newNode(3);head.next.next.Prev=head.next;head=reverse(head);printList(head);}}
JavaScript
classNode{constructor(val){this.data=val;this.next=null;this.prev=null;}}functionreverse(curr){// Base case: if the list is empty // or we reach the end of the listif(curr===null){returnnull;}// Swap the next and prev pointersconsttemp=curr.prev;curr.prev=curr.next;curr.next=temp;// If the previous node (after swap) is null,// this is the new headif(curr.prev===null){returncurr;}returnreverse(curr.prev);}functionprintList(node){letoutput='';while(node!==null){output+=node.data;if(node.next!==null)output+=" <-> ";node=node.next;}console.log(output.trim());}// Driver Codeconsthead=newNode(1);head.next=newNode(2);head.next.prev=head;head.next.next=newNode(3);head.next.next.prev=head.next;constreversedHead=reverse(head);printList(reversedHead);
Output
3 <-> 2 <-> 1
[Expected Approach] Using Two Pointers - O(n) Time and O(1) Space
The idea is to reverse doubly linked list using two pointers for traversing through the list and swapping the next and previous pointers of every two consecutive nodes.
Step-by-step algorithm:
Initially, prevNode is set to NULL and currNode starts at the head.
As the list is traversed, => Swap the currNode->next and currNode->prev => Move currNode to the next node, currNode = currNode->prev.
After traversing all the nodes, prevNode will point to the second node of the reversed list, so update the previous pointer of prevNode as the new head of the linked list, head = prevNode->prev and return it.
Illustrations:
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*next;Node*prev;Node(intnew_data){data=new_data;next=NULL;prev=NULL;}};Node*reverse(Node*head){// If the list is empty or has only one node,// return the head as isif(head==nullptr||head->next==nullptr)returnhead;Node*prevNode=NULL;Node*currNode=head;// Traverse the list and reverse the linkswhile(currNode!=nullptr){// Swap the next and prev pointersprevNode=currNode->prev;currNode->prev=currNode->next;currNode->next=prevNode;// Move to the next node in the original list // (which is now previous due to reversal)currNode=currNode->prev;}returnprevNode->prev;}voidprintList(Node*node){while(node!=nullptr){cout<<node->data;if(node->next!=nullptr){cout<<" <-> ";}node=node->next;}cout<<endl;}intmain(){Node*head=newNode(1);head->next=newNode(2);head->next->prev=head;head->next->next=newNode(3);head->next->next->prev=head->next;head=reverse(head);printList(head);return0;}
C
#include<stdio.h>structNode{intdata;structNode*next;structNode*prev;};structNode*reverse(structNode*head){if(head==NULL||head->next==NULL)returnhead;structNode*prevNode=NULL;structNode*currNode=head;// Traverse the list and reverse the linkswhile(currNode!=NULL){// Swap the next and prev pointersprevNode=currNode->prev;currNode->prev=currNode->next;currNode->next=prevNode;// Move to the next node in the original list // (which is now previous due to reversal)currNode=currNode->prev;}if(prevNode!=NULL)head=prevNode->prev;returnhead;}voidprintList(structNode*node){while(node!=NULL){printf("%d",node->data);if(node->next!=NULL){printf(" <-> ");}node=node->next;}printf("\n");}structNode*createNode(intnew_data){structNode*new_node=(structNode*)malloc(sizeof(structNode));new_node->data=new_data;new_node->next=NULL;new_node->prev=NULL;returnnew_node;}intmain(){structNode*head=createNode(1);head->next=createNode(2);head->next->prev=head;head->next->next=createNode(3);head->next->next->prev=head->next;head=reverse(head);printList(head);return0;}
Java
classNode{intdata;Nodenext;Nodeprev;Node(intdata){this.data=data;this.next=null;this.prev=null;}}publicclassGfG{staticNodereverse(Nodehead){if(head==null||head.next==null){returnhead;}NodecurrNode=head;NodeprevNode=null;// Traverse the list and reverse the linkswhile(currNode!=null){// Swap the next and prev pointersprevNode=currNode.prev;currNode.prev=currNode.next;currNode.next=prevNode;// Move to the next node in the original list// (which is now previous due to reversal)currNode=currNode.prev;}head=prevNode.prev;returnhead;}staticvoidprintList(Nodenode){while(node!=null){System.out.print(node.data);if(node.next!=null){System.out.print(" <-> ");}node=node.next;}System.out.println();}publicstaticvoidmain(String[]args){Nodehead=newNode(1);head.next=newNode(2);head.next.prev=head;head.next.next=newNode(3);head.next.next.prev=head.next;head=reverse(head);printList(head);}}
Python
classNode:def__init__(self,new_data):self.data=new_dataself.next=Noneself.prev=Nonedefreverse(head):# If the list is empty or has only one node,# return the head as isifheadisNoneorhead.nextisNone:returnheadprevNode=NonecurrNode=head# Traverse the list and reverse the linkswhilecurrNodeisnotNone:# Swap the next and prev pointersprevNode=currNode.prevcurrNode.prev=currNode.nextcurrNode.next=prevNode# Move to the next node in the original list# (which is now previous due to reversal)currNode=currNode.prevreturnprevNode.prevdefprintList(node):whilenodeisnotNone:print(node.data,end="")ifnode.nextisnotNone:print(" <-> ",end="")node=node.nextprint()if__name__=="__main__":head=Node(1)head.next=Node(2)head.next.prev=headhead.next.next=Node(3)head.next.next.prev=head.nexthead=reverse(head)printList(head)
C#
usingSystem;classNode{publicintData;publicNodenext;publicNodeprev;publicNode(intnewData){Data=newData;next=null;prev=null;}}classGfG{staticNodereverse(Nodehead){// If the list is empty or has only one node,// return the head as isif(head==null||head.next==null)returnhead;NodeprevNode=null;NodecurrNode=head;// Traverse the list and reverse the linkswhile(currNode!=null){// Swap the next and prev pointersprevNode=currNode.prev;currNode.prev=currNode.next;currNode.next=prevNode;// Move to the next node in the original list// (which is now previous due to reversal)currNode=currNode.prev;}returnprevNode.prev;}staticvoidprintList(Nodenode){while(node!=null){Console.Write(node.Data);if(node.next!=null){Console.Write(" <-> ");}node=node.next;}Console.WriteLine();}publicstaticvoidMain(){Nodehead=newNode(1);head.next=newNode(2);head.next.prev=head;head.next.next=newNode(3);head.next.next.prev=head.next;head=reverse(head);printList(head);}}
JavaScript
classNode{constructor(new_data){this.data=new_data;this.next=null;this.prev=null;}}functionreverse(head){// If the list is empty or has only one node,// return the head as isif(head===null||head.next===null)returnhead;letprevNode=null;letcurrNode=head;// Traverse the list and reverse the linkswhile(currNode!==null){// Swap the next and prev pointersprevNode=currNode.prev;currNode.prev=currNode.next;currNode.next=prevNode;// Move to the next node in the original list // (which is now previous due to reversal)currNode=currNode.prev;}returnprevNode.prev;}functionprintList(node){letoutput="";while(node!==null){output+=node.data;if(node.next!=null){output+=" <-> ";}node=node.next;}console.log(output);}// Driver Codelethead=newNode(1);head.next=newNode(2);head.next.prev=head;head.next.next=newNode(3);head.next.next.prev=head.next;head=reverse(head);printList(head);