Rearrange a given linked list in-place
Last Updated :
04 Sep, 2024
Given a singly linked list L0 -> L1 -> … -> Ln-1 -> Ln. Rearrange the nodes in the list so that the newly formed list is : L0 -> Ln -> L1 -> Ln-1 -> L2 -> Ln-2 ... You are required to do this in place without altering the nodes' values.
Examples:
Input: 1 -> 2 -> 3 -> 4
Output: 1 -> 4 -> 2 -> 3
Explanation: Here n = 4, so the correct order is L0->L3->L1->L2
Input: 1 -> 2 -> 3 -> 4 -> 5
Output: 1 -> 5 -> 2 -> 4 -> 3
Explanation: Here n = 4, so the correct order is L0->L4->L1->L3->L2
[Naive Approach] Using two nested loops- O(n^2) Time and O(1) Space
The idea is to start traversing from head node. For each node, perform the following operations:
- Traverse the list to find the last node.
- Disconnect the last node from the list.
- Place the removed last node after the current node.
- Update current to its next node.
[Efficient Approach] By Reversing Second Half - O(n) Time and O(1) Space
- Find the middle of the linked list using the fast and slow pointer method. This involves moving one pointer twice as fast as the other so that when the faster pointer reaches the end, the slower pointer will be at the middle.
- Reverse the second half of the list starting just after the middle node and split them in two parts.
- Merge the two halves together by alternating nodes from the first half with nodes from the reversed second half.
Below is the implementation of the above approach :
C++
// C++ code to rearrange a given linked list in-place
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *next;
Node(int x) {
data = x;
next = NULL;
}
};
Node *reverselist(Node *head) {
Node *prev = nullptr, *curr = head, *next;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
void printList(Node *curr) {
while (curr != nullptr) {
cout << curr->data << " ";
curr = curr->next;
}
}
// Function to rearrange a linked list
Node *rearrange(Node *head) {
// Find the middle point using tortoise and hare method
Node *slow = head, *fast = slow->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
// Split the linked list into two halves
Node *head1 = head;
Node *head2 = slow->next;
slow->next = NULL;
// Reverse the second half
head2 = reverselist(head2);
// Merge alternate nodes
head = new Node(0);
Node *curr = head;
while (head1 || head2) {
// First add the element from the first list
if (head1) {
curr->next = head1;
curr = curr->next;
head1 = head1->next;
}
// Then add the element from the second list
if (head2) {
curr->next = head2;
curr = curr->next;
head2 = head2->next;
}
}
// Return the head of the new list
return head->next;
}
int main() {
// singly linked list 1->2->3->4->5
Node *head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(4);
head->next->next->next->next = new Node(5);
head = rearrange(head);
printList(head);
return 0;
}
C
// C code to rearrange a given linked list in-place
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *reverselist(struct Node *head) {
// Initialize prev and current pointers
struct Node *prev = NULL, *curr = head, *next;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
void printList(struct Node *curr) {
while (curr != NULL) {
printf("%d ", curr->data);
curr = curr->next;
}
}
// Function to rearrange a linked list
struct Node *rearrange(struct Node *head) {
// Find the middle point using tortoise
// and hare method
struct Node *slow = head, *fast = slow->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
// Split the linked list into two halves
// head1, head of first half
// head2, head of second half
struct Node *head1 = head;
struct Node *head2 = slow->next;
slow->next = NULL;
// Reverse the second half
head2 = reverselist(head2);
// Merge alternate nodes
struct Node dummy;
struct Node *curr = &dummy;
dummy.next = NULL;
while (head1 || head2) {
// First add the element from head1
if (head1) {
curr->next = head1;
curr = curr->next;
head1 = head1->next;
}
// Then add the element from head2
if (head2) {
curr->next = head2;
curr = curr->next;
head2 = head2->next;
}
}
return dummy.next;
}
struct Node *newNode(int key) {
struct Node *temp =
(struct Node *)malloc(sizeof(struct Node));
temp->data = key;
temp->next = NULL;
return temp;
}
int main() {
// singly linked list 1->2->3->4->5
struct Node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3);
head->next->next->next = newNode(4);
head->next->next->next->next = newNode(5);
head = rearrange(head);
printList(head);
return 0;
}
Java
// Java code to rearrange a given linked list in-place
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
class GfG {
static void printList(Node node) {
if (node == null) {
return;
}
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
static Node reverseList(Node node) {
Node prev = null, curr = node, next;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Method to rearrange the linked list
static Node rearrange(Node node) {
// Check if the list is empty or has only one node
if (node == null || node.next == null) {
return node;
}
// Find the middle point using tortoise and hare
// method
Node slow = node, fast = node.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// Split the linked list into two halves
Node firstHalf = node;
Node secondHalf = slow.next;
slow.next = null;
// Reverse the second half of the list
secondHalf = reverseList(secondHalf);
// Merge alternate nodes from the two halves
Node dummy = new Node(0);
Node curr = dummy;
while (firstHalf != null || secondHalf != null) {
if (firstHalf != null) {
curr.next = firstHalf;
curr = curr.next;
firstHalf = firstHalf.next;
}
if (secondHalf != null) {
curr.next = secondHalf;
curr = curr.next;
secondHalf = secondHalf.next;
}
}
// Return the new head of the rearranged list
return dummy.next;
}
public static void main(String[] args){
// singly linked list 1->2->3->4->5
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
head = rearrange(head);
printList(head);
}
}
Python
# Python program to rearrange link list in place
class Node:
def __init__(self, d):
self.data = d
self.next = None
def printlist(node):
if node is None:
return
while node is not None:
print(node.data, end=" ")
node = node.next
def reverselist(node):
prev = None
curr = node
next = None
while curr is not None:
next = curr.next
curr.next = prev
prev = curr
curr = next
node = prev
return node
def rearrange(node):
# Find the middle point using the
# tortoise and hare method
slow = node
fast = slow.next
while fast is not None and fast.next is not None:
slow = slow.next
fast = fast.next.next
# Split the linked list into two halves
node1 = node
node2 = slow.next
slow.next = None
# Reverse the second half
node2 = reverselist(node2)
# Merge alternate nodes
node = Node(0)
curr = node
while node1 is not None or node2 is not None:
# Add the element from the first list
if node1 is not None:
curr.next = node1
curr = curr.next
node1 = node1.next
# Add the element from the second list
if node2 is not None:
curr.next = node2
curr = curr.next
node2 = node2.next
# Return the head of the rearranged list
return node.next
# singly linked list 1->2->3->4->5
head = None
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head = rearrange(head)
printlist(head)
C#
// C# program to rearrange link list in place
using System;
public class Node {
public int Data;
public Node Next;
public Node(int data) {
Data = data;
Next = null;
}
}
class GfG {
static void PrintList(Node node) {
if (node == null) {
Console.WriteLine("List is empty.");
return;
}
while (node != null) {
Console.Write(node.Data + " ");
node = node.Next;
}
}
static Node ReverseList(Node node) {
Node prev = null;
Node curr = node;
Node next = null;
while (curr != null) {
next = curr.Next;
curr.Next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Method to rearrange the linked list in-place and
// return the new head
static Node Rearrange(Node node) {
if (node == null || node.Next == null)
return node;
// Find the middle point using tortoise and hare
// method
Node slow = node;
Node fast = node.Next;
while (fast != null && fast.Next != null) {
slow = slow.Next;
fast = fast.Next.Next;
}
// Split the linked list into two halves
Node firstHalf = node;
Node secondHalf = slow.Next;
slow.Next = null;
// Reverse the second half
secondHalf = ReverseList(secondHalf);
// Merge alternate nodes
Node dummy = new Node(0);
Node curr = dummy;
while (firstHalf != null || secondHalf != null) {
if (firstHalf != null) {
curr.Next = firstHalf;
curr = curr.Next;
firstHalf = firstHalf.Next;
}
if (secondHalf != null) {
curr.Next = secondHalf;
curr = curr.Next;
secondHalf = secondHalf.Next;
}
}
// Return the new head of the list
return dummy.Next;
}
public static void Main(string[] args) {
//singly linked list 1->2->3->4->5
Node head = new Node(1);
head.Next = new Node(2);
head.Next.Next = new Node(3);
head.Next.Next.Next = new Node(4);
head.Next.Next.Next.Next = new Node(5);
head = Rearrange(head);
PrintList(head);
}
}
JavaScript
// Javascript program to rearrange link list in place
class Node {
constructor(d) {
this.data = d;
this.next = null;
}
}
function printList(node) {
let result = "";
while (node != null) {
result += node.data + " ";
node = node.next;
}
console.log(result);
}
function reverseList(node) {
let prev = null, curr = node, next;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to rearrange the linked list
function rearrange(head) {
if (head == null || head.next == null) {
return head;
}
// Find the middle point using
// tortoise and hare method
let slow = head, fast = slow.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// Split the linked list into two halves
let node1 = head;
let node2 = slow.next;
slow.next = null;
// Reverse the second half
node2 = reverseList(node2);
// Merge alternate nodes
let dummy = new Node(0);
let curr = dummy;
while (node1 != null || node2 != null) {
if (node1 != null) {
curr.next = node1;
curr = curr.next;
node1 = node1.next;
}
if (node2 != null) {
curr.next = node2;
curr = curr.next;
node2 = node2.next;
}
}
return dummy.next;
}
// singly linked list 1->2->3->4->5
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
head = rearrange(head);
printList(head);
Time Complexity: O(n) , where n are the number of nodes in linked list.
Auxiliary Space: O(1)
Similar Reads
Javascript Program For Rearranging A Given Linked List In-Place Given a singly linked list L0 -> L1 -> ⦠-> Ln-1 -> Ln. Rearrange the nodes in the list so that the new formed list is : L0 -> Ln -> L1 -> Ln-1 -> L2 -> Ln-2 ...You are required to do this in place without altering the nodes' values. Examples: Input: 1 -> 2 -> 3 -
7 min read
Rearrange a Linked List in Zig-Zag fashion Given a linked list, rearrange it such that the converted list should be of the form a < b > c < d > e < f ⦠where a, b, c⦠are consecutive data nodes of the linked list. Examples: Input: 1->2->3->4 Output: 1->3->2->4 Explanation : 1 and 3 should come first before 2
15+ min read
Rearrange a Linked List in Zig-Zag fashion | Set-2 Given a linked list, rearrange it such that converted list should be of the form a < b > c < d > e < f .. where a, b, c.. are consecutive data node of linked list. Note that it is not allowed to swap data. Examples: Input: 1->2->3->4 Output: 1->3->2->4 Input: 11->
13 min read
Make middle node head in a linked list Given a singly linked list, find middle of the linked list and set middle node of the linked list at beginning of the linked list. Examples: Input : 1 2 3 4 5 Output : 3 1 2 4 5 Input : 1 2 3 4 5 6 Output : 4 1 2 3 5 6 The idea is to first find middle of a linked list using two pointers, first one m
10 min read
Can we reverse a linked list in less than O(n)? It is not possible to reverse a simple singly linked list in less than O(n). A simple singly linked list can only be reversed in O(n) time using recursive and iterative methods. A doubly linked list with head and tail pointers while only requiring swapping the head and tail pointers which require le
1 min read
Reverse a Linked List Given a linked list, the task is to reverse the linked list by changing the links between nodes.Examples: Input: head: 1 -> 2 -> 3 -> 4 -> NULLOutput: head: 4 -> 3 -> 2 -> 1 -> NULLExplanation: Reversed Linked List: Input: head: 1 -> 2 -> 3 -> 4 -> 5 -> NULLOut
15+ min read
Reverse first K elements of given linked list Given a pointer to the head node of a linked list and a number K, the task is to reverse the first K nodes of the linked list. We need to reverse the list by changing links between nodes. check also Reversal of a linked list Examples: Input : 1->2->3->4->5->6->7->8->9->10-
9 min read
Modify and Rearrange List Given a singly linked list, with some positive numbers (valid numbers) and zeros (invalid numbers). Convert the linked list in such a way that if next valid number is same as current number, double its value and replace the next number with 0. After the modification, rearrange the linked list such t
13 min read
Reverse a circular linked list Given a circular linked list of size n. The problem is to reverse the given circular linked list by changing links between the nodes.Examples: INPUT: OUTPUT: Approach: The approach is same as followed in reversing a singly linked list. Only here we have to make one more adjustment by linking the las
7 min read
Insert a Node after a given node in Doubly Linked List Given a Doubly Linked List, the task is to insert a new node after a given node in the linked list.Examples: Input: Linked List = 1 <-> 2 <-> 4, newData = 3, key = 2Output: Linked List = 1 <-> 2 <-> 3 <-> 4Explanation: New node 3 is inserted after key, that is node 2.In
11 min read