Reverse Linked list by reducing segment size from both ends
Given a linked list of even length, where each element is an integer, the task is to reverse the list by performing the following steps repeatedly, after completing the below steps, return the new head of the list.
- Reverse the list and remove the first and last elements.
- Repeat step 1 until there are no more elements left.
Note: You are not allowed to use extra memory other than creating some new nodes required for the implementation.
Examples:
Input: 1 -> 5 -> 2 -> 7 -> 8 -> 3 -> NULL
Output: 3 -> 5 -> 7 -> 2 -> 8 -> 1 -> NULL
Explanation: The initial linked list is : 1 -> 5 -> 2 -> 7 -> 8 -> 3 -> NULL
Reverse the complete list: 3 -> 8 -> 7 -> 2 -> 5 -> 1 -> NULL
Reduce the segment by 1 from both ends and reverse the list: 3 -> 5 -> 2 -> 7 -> 8 -> 1 -> NULL
Reduce the segment by 1 from both ends and reverse the list: 3 -> 5 -> 7 -> 2 -> 8 -> 1 -> NULLInput: 3 -> 4 -> 7 -> 8 -> NULL
Output: 8 -> 4 -> 7 -> 3 -> NULL
Approach: To solve the problem follow the below idea:
The idea is to traverse the half of the list and swap the values of nodes with the values of corresponding nodes on opposite sides of the list.
Below are the steps for the above approach:
- Initialize two pointers fast and slow to the head of the list, and a variable to store the length of the list length = 0.
- Traverse the list using the two-pointers. At each step, the fast pointer moves two steps forward and the slow pointer moves one step forward and increments the length variable by 2 at each step.
- Initialize a pointer node = head to traverse the list during the next phase.
- Iterate over half of the list (i.e., the first length/2 nodes) from i = 0 to t < length/2.
- For each iteration, check if the index of the current node being swapped is even.
- Initialize a temporary pointer temp = slow pointer as it is at mid+1 index and counts how many steps to move right to reach the right pointer of this segment,
count = length/2 – i – 1, Run a loop while count > 0, move temp pointer forward and decrement the count. - Swap the values or nodes of the current node with the corresponding node on the right temp. If the index is odd, simply move to the next node.
- Initialize a temporary pointer temp = slow pointer as it is at mid+1 index and counts how many steps to move right to reach the right pointer of this segment,
- Continue this process until it has swapped all the nodes on one side of the list with the corresponding nodes on the opposite side of the list.
- Return the pointer to the new head of the reversed list.
Below is the code for the above approach:
C++
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std; struct Node { int val; Node* next; Node( int val) : val(val), next(nullptr) { } }; // Function to reverse the linked list Node* reverse(Node* head) { Node* fast = head; Node* slow = head; int length = 0; // Find length of linked list while (fast != nullptr && fast->next != nullptr) { fast = fast->next->next; slow = slow->next; length += 2; } Node* node = head; // Reversing the list for ( int i = 0; i < length / 2; i++) { if (i % 2 == 0) { // Assign the slow pointer as // it is at mid + 1 index Node* temp = slow; // How many steps to move right // to reach right pointer of // this segment int count = length / 2 - i - 1; while (count > 0) { temp = temp->next; count--; } // Swap their values or you // can also swap the nodes int val = node->val; node->val = temp->val; temp->val = val; node = node->next; } else { node = node->next; } } return head; } // Print the list void printList(Node* node) { while (node != nullptr) { cout << node->val << " " ; node = node->next; } } // Driver code int main() { Node* head = new Node(1); head->next = new Node(5); head->next->next = new Node(2); head->next->next->next = new Node(7); head->next->next->next->next = new Node(8); head->next->next->next->next->next = new Node(3); cout << "Given linked list" << endl; printList(head); head = reverse(head); cout << endl << "Reversed linked list" << endl; printList(head); return 0; } |
Java
/*package whatever // do not write package name here */ import java.io.*; class GFG { public static Node reverse(Node head) { Node fast = head; Node slow = head; int length = 0 ; // find length of linked list while (fast != null && fast.next != null ) { fast = fast.next.next; slow = slow.next; length += 2 ; } Node node = head; // reversing the list for ( int i = 0 ; i < length / 2 ; i++) { if (i % 2 == 0 ) { Node temp = slow; // assign the slow pointer as it is at mid + 1 index int count = length / 2 - i - 1 ; // how many steps to move right to reach right pointer of this segment while (count > 0 ) { temp = temp.next; count--; } int val = node.val; // swap their values or you can also swap the nodes node.val = temp.val; temp.val = val; node = node.next; } else { node = node.next; } } return head; } // print the list public static void printList(Node node) { while (node != null ) { System.out.print(node.val + " " ); node = node.next; } } public static void main(String[] args) { Node head = new Node( 1 ); head.next = new Node( 5 ); head.next.next = new Node( 2 ); head.next.next.next = new Node( 7 ); head.next.next.next.next = new Node( 8 ); head.next.next.next.next.next = new Node( 3 ); System.out.println( "Given linked list" ); printList(head); head = reverse(head); System.out.println( "" ); System.out.println( "Reversed linked list " ); printList(head); } } class Node { int val; Node next; Node( int val) { this .val = val; next = null ; } } // This code has been contributed by vishalkumarsahu04 |
Python3
class Node: def __init__( self , val): self .val = val self . next = None def reverse(head): fast = head slow = head length = 0 # find length of linked list while fast and fast. next : fast = fast. next . next slow = slow. next length + = 2 node = head # reversing the list for i in range (length / / 2 ): if i % 2 = = 0 : temp = slow # assign the slow pointer as it is at mid + 1 index count = length / / 2 - i - 1 # how many steps to move right to reach right pointer of this segment while count > 0 : temp = temp. next count - = 1 val = node.val # swap their values or you can also swap the nodes node.val = temp.val temp.val = val node = node. next else : node = node. next return head # print the list def printList(node): while node: print (node.val, end = " " ) node = node. next # test the implementation head = Node( 1 ) head. next = Node( 5 ) head. next . next = Node( 2 ) head. next . next . next = Node( 7 ) head. next . next . next . next = Node( 8 ) head. next . next . next . next . next = Node( 3 ) print ( "Given linked list" ) printList(head) head = reverse(head) print ( "\nReversed linked list " ) printList(head) |
C#
// C# code for the above approach: using System; public class Node { public int val; public Node next; public Node( int val) { this .val = val; this .next = null ; } } public class GFG { // Function to reverse the linked list public static Node Reverse(Node head) { Node fast = head; Node slow = head; int length = 0; // Find length of linked list while (fast != null && fast.next != null ) { fast = fast.next.next; slow = slow.next; length += 2; } Node node = head; // Reversing the list for ( int i = 0; i < length / 2; i++) { if (i % 2 == 0) { // Assign the slow pointer as // it is at mid + 1 index Node temp = slow; // How many steps to move right // to reach right pointer of // this segment int count = length / 2 - i - 1; while (count > 0) { temp = temp.next; count--; } // Swap their values or you // can also swap the nodes int val = node.val; node.val = temp.val; temp.val = val; node = node.next; } else { node = node.next; } } return head; } public static void PrintList(Node node) { while (node != null ) { Console.Write(node.val + " " ); node = node.next; } } // Driver code public static void Main( string [] args) { Node head = new Node(1); head.next = new Node(5); head.next.next = new Node(2); head.next.next.next = new Node(7); head.next.next.next.next = new Node(8); head.next.next.next.next.next = new Node(3); // Print the list Console.WriteLine( "Given linked list" ); PrintList(head); // Function Call head = Reverse(head); // Print the list Console.WriteLine( "\nReversed linked list" ); PrintList(head); } } |
Javascript
// JavaScript code for the approach class Node { constructor(val) { this .val = val; this .next = null ; } } // Function to reverse the linked list function reverse(head) { let fast = head; let slow = head; let length = 0; // Find length of linked list while (fast != null && fast.next != null ) { fast = fast.next.next; slow = slow.next; length += 2; } let node = head; // Reversing the list for (let i = 0; i < length / 2; i++) { if (i % 2 == 0) { // Assign the slow pointer as // it is at mid + 1 index let temp = slow; // How many steps to move right // to reach right pointer of // this segment let count = length / 2 - i - 1; while (count > 0) { temp = temp.next; count--; } // Swap their values or you // can also swap the nodes let val = node.val; node.val = temp.val; temp.val = val; node = node.next; } else { node = node.next; } } return head; } // Print the list function printList(node) { let res = '' ; while (node !== null ) { res += node.val + ' ' ; node = node.next; } return res.trim(); } // Driver code let head = new Node(1); head.next = new Node(5); head.next.next = new Node(2); head.next.next.next = new Node(7); head.next.next.next.next = new Node(8); head.next.next.next.next.next = new Node(3); console.log( "Given linked list" ); console.log(printList(head)); head = reverse(head); console.log( "Reversed linked list" ); console.log(printList(head)); |
Given linked list 1 5 2 7 8 3 Reversed linked list 3 5 7 2 8 1
Time Complexity: O(N)
Auxiliary Space: O(1)
Please Login to comment...