Reverse Linked list by reducing segment size from both ends
Last Updated :
03 Apr, 2023
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 -> NULL
Input: 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.
- 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++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int val;
Node* next;
Node( int val)
: val(val), next(nullptr)
{
}
};
Node* reverse(Node* head)
{
Node* fast = head;
Node* slow = head;
int length = 0;
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
length += 2;
}
Node* node = head;
for ( int i = 0; i < length / 2; i++) {
if (i % 2 == 0) {
Node* temp = slow;
int count = length / 2 - i - 1;
while (count > 0) {
temp = temp->next;
count--;
}
int val = node->val;
node->val = temp->val;
temp->val = val;
node = node->next;
}
else {
node = node->next;
}
}
return head;
}
void printList(Node* node)
{
while (node != nullptr) {
cout << node->val << " " ;
node = node->next;
}
}
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
import java.io.*;
class GFG {
public static Node reverse(Node head)
{
Node fast = head;
Node slow = head;
int length = 0 ;
while (fast != null && fast.next != null ) {
fast = fast.next.next;
slow = slow.next;
length += 2 ;
}
Node node = head;
for ( int i = 0 ; i < length / 2 ; i++) {
if (i % 2 == 0 ) {
Node temp = slow;
int count = length / 2 - i - 1 ;
while (count > 0 ) {
temp = temp.next;
count--;
}
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 ) {
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 ;
}
}
|
Python3
class Node:
def __init__( self , val):
self .val = val
self . next = None
def reverse(head):
fast = head
slow = head
length = 0
while fast and fast. next :
fast = fast. next . next
slow = slow. next
length + = 2
node = head
for i in range (length / / 2 ):
if i % 2 = = 0 :
temp = slow
count = length / / 2 - i - 1
while count > 0 :
temp = temp. next
count - = 1
val = node.val
node.val = temp.val
temp.val = val
node = node. next
else :
node = node. next
return head
def printList(node):
while node:
print (node.val, end = " " )
node = node. next
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#
using System;
public class Node {
public int val;
public Node next;
public Node( int val) {
this .val = val;
this .next = null ;
}
}
public class GFG {
public static Node Reverse(Node head) {
Node fast = head;
Node slow = head;
int length = 0;
while (fast != null && fast.next != null ) {
fast = fast.next.next;
slow = slow.next;
length += 2;
}
Node node = head;
for ( int i = 0; i < length / 2; i++) {
if (i % 2 == 0) {
Node temp = slow;
int count = length / 2 - i - 1;
while (count > 0) {
temp = temp.next;
count--;
}
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;
}
}
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);
Console.WriteLine( "Given linked list" );
PrintList(head);
head = Reverse(head);
Console.WriteLine( "\nReversed linked list" );
PrintList(head);
}
}
|
Javascript
class Node {
constructor(val) {
this .val = val;
this .next = null ;
}
}
function reverse(head) {
let fast = head;
let slow = head;
let length = 0;
while (fast != null && fast.next != null ) {
fast = fast.next.next;
slow = slow.next;
length += 2;
}
let node = head;
for (let i = 0; i < length / 2; i++) {
if (i % 2 == 0) {
let temp = slow;
let count = length / 2 - i - 1;
while (count > 0) {
temp = temp.next;
count--;
}
let val = node.val;
node.val = temp.val;
temp.val = val;
node = node.next;
}
else {
node = node.next;
}
}
return head;
}
function printList(node) {
let res = '' ;
while (node !== null ) {
res += node.val + ' ' ;
node = node.next;
}
return res.trim();
}
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));
|
Output
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)
Share your thoughts in the comments
Please Login to comment...