Given a doubly-linked list, the task is to rotate the linked list counter-clockwise by p nodes. Here p is a given positive integer and is smaller than the count of nodes in the linked list.
Examples:
Input:
Output:
Explanation: After rotating the list by p = 2, the new head will be the node with value 3.
Input:
Output:
Explanation: After rotating the list by p = 3, the new head will be the node with value 4.
[Expected Approach - 1] Making a Circular DLL - O(n) Time and O(1) Space
The idea is to make the list circular by connecting the tail to the head. Then, we move the head and tail pointers p positions forward, and finally, break the circular link to restore the list’s original structure with the new head and tail. This approach efficiently rotates the list by adjusting the links without rearranging node data.
Working of Approach:
Link the last node's next pointer to the head and set the head's prev pointer to the tail.
Traverse the list by p positions to shift the head to the new position and adjust the tail accordingly.
Set the new tail’s next pointer to null and the new head’s prev pointer to null.
The new head is now at the desired position after the rotation.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*prev;Node*next;Node(intx){data=x;prev=nullptr;next=nullptr;}};// Function to rotate the doubly-linked listNode*rotateDLL(Node*head,intp){Node*tail=head;// Find the last nodewhile(tail->next){tail=tail->next;}// Make the list circulartail->next=head;head->prev=tail;// Move head and tail by the given positionfor(intcount=1;count<=p;count++){head=head->next;tail=tail->next;}// Break the circular connectiontail->next=nullptr;head->prev=nullptr;returnhead;}voidprintList(Node*head){Node*curr=head;while(curr){cout<<curr->data;if(curr->next)cout<<" ";curr=curr->next;}cout<<endl;}intmain(){Node*head=newNode(2);head->next=newNode(6);head->next->prev=head;head->next->next=newNode(5);head->next->next->prev=head->next;head->next->next->next=newNode(4);head->next->next->next->prev=head->next->next;intp=3;head=rotateDLL(head,p);printList(head);return0;}
Java
classNode{intdata;Nodeprev,next;Node(intx){data=x;prev=null;next=null;}}classGfG{// Function to rotate the doubly-linked liststaticNoderotateDLL(Nodehead,intp){Nodetail=head;// Find the last nodewhile(tail.next!=null){tail=tail.next;}// Make the list circulartail.next=head;head.prev=tail;// Move head and tail by the given positionfor(intcount=1;count<=p;count++){head=head.next;tail=tail.next;}// Break the circular connectiontail.next=null;head.prev=null;returnhead;}staticvoidprintList(Nodehead){Nodecurr=head;while(curr!=null){System.out.print(curr.data);if(curr.next!=null){System.out.print(" ");}curr=curr.next;}System.out.println();}publicstaticvoidmain(String[]args){Nodehead=newNode(2);head.next=newNode(6);head.next.prev=head;head.next.next=newNode(5);head.next.next.prev=head.next;head.next.next.next=newNode(4);head.next.next.next.prev=head.next.next;intp=3;head=rotateDLL(head,p);printList(head);}}
Python
classNode:def__init__(self,x):self.data=xself.prev=Noneself.next=None# Function to rotate the doubly-linked listdefrotateDLL(head,p):tail=head# Find the last nodewhiletail.next:tail=tail.next# Make the list circulartail.next=headhead.prev=tail# Move head and tail by the given positionforiinrange(p):head=head.nexttail=tail.next# Break the circular connectiontail.next=Nonehead.prev=NonereturnheaddefprintList(head):curr=headwhilecurr:print(curr.data,end="")ifcurr.next:print(" ",end="")curr=curr.nextprint()if__name__=="__main__":head=Node(2)head.next=Node(6)head.next.prev=headhead.next.next=Node(5)head.next.next.prev=head.nexthead.next.next.next=Node(4)head.next.next.next.prev=head.next.nextp=3head=rotateDLL(head,p)printList(head)
C#
usingSystem;classNode{publicintdata;publicNodeprev;publicNodenext;publicNode(intx){data=x;prev=null;next=null;}}classGfG{// Function to rotate the doubly-linked liststaticNoderotateDLL(Nodehead,intp){Nodetail=head;// Find the last nodewhile(tail.next!=null){tail=tail.next;}// Make the list circulartail.next=head;head.prev=tail;// Move head and tail by the given positionfor(intcount=1;count<=p;count++){head=head.next;tail=tail.next;}// Break the circular connectiontail.next=null;head.prev=null;returnhead;}staticvoidprintList(Nodehead){Nodecurr=head;while(curr!=null){Console.Write(curr.data);if(curr.next!=null)Console.Write(" ");curr=curr.next;}Console.WriteLine();}staticvoidMain(string[]args){Nodehead=newNode(2);head.next=newNode(6);head.next.prev=head;head.next.next=newNode(5);head.next.next.prev=head.next;head.next.next.next=newNode(4);head.next.next.next.prev=head.next.next;intp=3;head=rotateDLL(head,p);printList(head);}}
JavaScript
classNode{constructor(x){this.data=x;this.prev=null;this.next=null;}}// Function to rotate the doubly linked listfunctionrotateDLL(head,p){if(head===null)returnnull;lettail=head;// Find the last nodewhile(tail.next!==null){tail=tail.next;}// Make the list circulartail.next=head;head.prev=tail;// Move head and tail by p positionsfor(letcount=1;count<=p;count++){head=head.next;tail=tail.next;}// Break the circular connectiontail.next=null;head.prev=null;returnhead;}// Function to print the listfunctionprintList(head){letcurr=head;letresult="";while(curr!==null){result+=curr.data;if(curr.next!==null){result+=" ";}curr=curr.next;}console.log(result);}// Driver codelethead=newNode(2);head.next=newNode(6);head.next.prev=head;head.next.next=newNode(5);head.next.next.prev=head.next;head.next.next.next=newNode(4);head.next.next.next.prev=head.next.next;letp=3;head=rotateDLL(head,p);printList(head);
Output
4 2 6 5
[Expected Approach - 2] Break at pth node and Link - O(n) Time and O(1) Space
The idea is to first find the p-th node, then adjust the prev and next pointers to disconnect the list, re-link it, and make the new head the node after the p-th node. Finally, we reconnect the list's tail to the original head to maintain continuity.
Working of Approach:
Move to the node at position p in the list.
Set the next pointer of the p-th node to null and the prev pointer of the next node to null.
Traverse the list from the new head to find the tail node.
Attach the original head node to the tail node and set the tail's next pointer to null.
The new head is now the node after the p-th node.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*prev;Node*next;Node(intx){data=x;prev=nullptr;next=nullptr;}};// Function to rotate the doubly-linked list by p nodesNode*rotateDLL(Node*head,intp){// If list is empty or no rotation neededif(!head||p==0)returnhead;// Find length of the doubly linked listintlen=0;Node*temp=head;while(temp){len++;temp=temp->next;}// Normalize p (in case p >= length)p=p%len;// If p becomes 0, no rotation requiredif(p==0)returnhead;Node*curr=head;// Traverse to the p-th nodefor(inti=1;i<p;i++){curr=curr->next;}// curr is now pointing to p-th nodeNode*newHead=curr->next;// Break the list at p-th nodenewHead->prev=nullptr;curr->next=nullptr;// Traverse to the last node of remaining listNode*tail=newHead;while(tail->next){tail=tail->next;}// Connect old tail with old headtail->next=head;head->prev=tail;// Return new head after rotationreturnnewHead;}voidprintList(Node*head){Node*curr=head;while(curr){cout<<curr->data;if(curr->next)cout<<" ";curr=curr->next;}cout<<endl;}intmain(){Node*head=newNode(2);head->next=newNode(6);head->next->prev=head;head->next->next=newNode(5);head->next->next->prev=head->next;head->next->next->next=newNode(4);head->next->next->next->prev=head->next->next;intp=3;head=rotateDLL(head,p);printList(head);return0;}
Java
/*package whatever //do not write package name here */importjava.io.*;classNode{intdata;Nodeprev;Nodenext;Node(intx){data=x;prev=null;next=null;}}classGfG{// Function to rotate the doubly-linked list by p nodesstaticNoderotateDLL(Nodehead,intp){if(head==null||p==0)returnhead;intlen=0;Nodetemp=head;while(temp!=null){len++;temp=temp.next;}p=p%len;if(p==0)returnhead;Nodecurr=head;for(inti=1;i<p;i++){curr=curr.next;}NodenewHead=curr.next;newHead.prev=null;curr.next=null;Nodetail=newHead;while(tail.next!=null){tail=tail.next;}tail.next=head;head.prev=tail;returnnewHead;}staticvoidprintList(Nodehead){Nodecurr=head;while(curr!=null){System.out.print(curr.data+" ");curr=curr.next;}System.out.println();}publicstaticvoidmain(String[]args){Nodehead=newNode(2);head.next=newNode(6);head.next.prev=head;head.next.next=newNode(5);head.next.next.prev=head.next;head.next.next.next=newNode(4);head.next.next.next.prev=head.next.next;intp=3;head=rotateDLL(head,p);printList(head);}}
Python
classNode:def__init__(self,data):self.data=dataself.prev=Noneself.next=None# Function to rotate the doubly-linked list by p nodesdefrotateDLL(head,p):# If list is empty or no rotation neededifnotheadorp==0:returnhead# Find length of the doubly linked listlength=0temp=headwhiletemp:length+=1temp=temp.next# Normalize p (in case p >= length)p=p%length# If p becomes 0, no rotation requiredifp==0:returnheadcurr=head# Traverse to the p-th nodeforiinrange(1,p):curr=curr.next# curr is now pointing to p-th nodenewHead=curr.next# Break the list at p-th nodenewHead.prev=Nonecurr.next=None# Traverse to the last node of remaining listtail=newHeadwhiletail.next:tail=tail.next# Connect old tail with old headtail.next=headhead.prev=tailreturnnewHead# Function to print the doubly-linked listdefprintList(head):curr=headwhilecurr:print(curr.data,end=" ")curr=curr.nextprint()# Driver codeif__name__=='__main__':head=Node(2)head.next=Node(6)head.next.prev=headhead.next.next=Node(5)head.next.next.prev=head.nexthead.next.next.next=Node(4)head.next.next.next.prev=head.next.nextp=3head=rotateDLL(head,p)printList(head)
C#
usingSystem;publicclassNode{publicintdata;publicNodeprev;publicNodenext;publicNode(intx){data=x;prev=null;next=null;}}classGfG{// Function to rotate the doubly-linked list by p nodespublicstaticNoderotateDLL(Nodehead,intp){// If list is empty or no rotation neededif(head==null||p==0)returnhead;// Find length of the doubly linked listintlen=0;Nodetemp=head;while(temp!=null){len++;temp=temp.next;}// Normalize p (in case p >= length)p=p%len;// If p becomes 0, no rotation requiredif(p==0)returnhead;Nodecurr=head;// Traverse to the p-th nodefor(inti=1;i<p;i++){curr=curr.next;}// curr is now pointing to p-th nodeNodenewHead=curr.next;// Break the list at p-th nodenewHead.prev=null;curr.next=null;// Traverse to the last node of remaining listNodetail=newHead;while(tail.next!=null){tail=tail.next;}// Connect old tail with old headtail.next=head;head.prev=tail;// Return new head after rotationreturnnewHead;}publicstaticvoidprintList(Nodehead){Nodecurr=head;while(curr!=null){Console.Write(curr.data);if(curr.next!=null)Console.Write(" ");curr=curr.next;}Console.WriteLine();}staticvoidMain(string[]args){Nodehead=newNode(2);head.next=newNode(6);head.next.prev=head;head.next.next=newNode(5);head.next.next.prev=head.next;head.next.next.next=newNode(4);head.next.next.next.prev=head.next.next;intp=3;head=rotateDLL(head,p);printList(head);}}
JavaScript
classNode{constructor(x){this.data=x;this.prev=null;this.next=null;}}// Function to rotate the doubly-linked list by p nodesfunctionrotateDLL(head,p){// If list is empty or no rotation neededif(!head||p===0)returnhead;// Find length of the doubly linked listletlen=0;lettemp=head;while(temp){len++;temp=temp.next;}// Normalize p (in case p >= length)p=p%len;// If p becomes 0, no rotation requiredif(p===0)returnhead;letcurr=head;// Traverse to the p-th nodefor(leti=1;i<p;i++){curr=curr.next;}// curr is now pointing to p-th nodeletnewHead=curr.next;// Break the list at p-th nodenewHead.prev=null;curr.next=null;// Traverse to the last node of remaining listlettail=newHead;while(tail.next){tail=tail.next;}// Connect old tail with old headtail.next=head;head.prev=tail;// Return new head after rotationreturnnewHead;}functionprintList(head){letcurr=head;while(curr){process.stdout.write(curr.data+' ');curr=curr.next;}console.log();}functionmain(){lethead=newNode(2);head.next=newNode(6);head.next.prev=head;head.next.next=newNode(5);head.next.next.prev=head.next;head.next.next.next=newNode(4);head.next.next.next.prev=head.next.next;letp=3;head=rotateDLL(head,p);printList(head);}main();