Open In App

Reverse Linked list by reducing segment size from both ends

Last Updated : 03 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// 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));


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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads