Given the head of a singly linked list, modify the list by pairing the first node with the last node, the second node with the second last node, and so on. For each pair:
- Replace the value of the first node with (value of the second node − value of the first node).
- Replace the value of the second node with the original value of the first node.
If the linked list has an odd number of nodes, the middle node remains unchanged. Return the head of the modified linked list.
Examples:
Input: 10 -> 4 -> 5 -> 3 -> 6
Output: -4 -> -1 -> 5 -> 4 -> 10Explanation:
The linked list has an odd number of nodes, so the middle node (5) remains unchanged.
Pair (10, 6): Update the first node to 6 - 10 = -4, and the last node becomes the original value of the first node, 10.
Pair (4, 3): Update the second node to 3 - 4 = -1, and the second last node becomes the original value of the second node, 4.Input: 2 -> 9 -> 8 -> 12 -> 7 -> 10
Output: 8 -> -2 -> 4 -> 8 -> 9 -> 2
Explanation:
The linked list has an even number of nodes.
Pair (2, 10): Update the first node to 10 - 2 = 8, and the last node becomes 2.
Pair (9, 7): Update the second node to 7 - 9 = -2, and the second last node becomes 9.
Pair (8, 12): Update the third node to 12 - 8 = 4, and the third last node becomes 8.
Table of Content
[Naive Approach] Store Node Values in an Array - O(n) Time and O(n) Space
The idea is to first store all the node values in an array. Using two pointers on the array, update the values according to the given rules. Finally, traverse the linked list again and replace each node's value with the corresponding updated value from the array.
Working of Approach:
- Traverse the linked list and store all node values in an array.
- Use two pointers, one at the beginning and the other at the end of the array.
- For each pair, update the first value to (second - first) and the second value to the original first value.
- If the list has an odd number of nodes, leave the middle value unchanged.
- Traverse the linked list again and copy the updated array values back to the nodes.
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int x) {
data = x;
next = nullptr;
}
};
Node* modifyTheList(Node* head) {
vector<int> values;
// Store all node values
for (Node* curr = head; curr != nullptr; curr = curr->next) {
values.push_back(curr->data);
}
int left = 0;
int right = values.size() - 1;
// Update paired values
while (left < right) {
int value = values[left];
values[left] = values[right] - value;
values[right] = value;
left++;
right--;
}
// Copy updated values back to the linked list
Node* curr = head;
for (int value : values) {
curr->data = value;
curr = curr->next;
}
return head;
}
void printList(Node* head) {
while (head != nullptr) {
cout << head->data;
if (head->next != nullptr) {
cout << " -> ";
}
head = head->next;
}
cout << endl;
}
int main() {
Node* head = new Node(10);
head->next = new Node(4);
head->next->next = new Node(5);
head->next->next->next = new Node(3);
head->next->next->next->next = new Node(6);
head = modifyTheList(head);
printList(head);
return 0;
}
import java.util.ArrayList;
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
}
}
class GFG {
static Node modifyTheList(Node head) {
ArrayList<Integer> values = new ArrayList<>();
// Store all node values
for (Node curr = head; curr != null; curr = curr.next) {
values.add(curr.data);
}
int left = 0;
int right = values.size() - 1;
// Update paired values
while (left < right) {
int value = values.get(left);
values.set(left, values.get(right) - value);
values.set(right, value);
left++;
right--;
}
// Copy updated values back to the linked list
Node curr = head;
for (int value : values) {
curr.data = value;
curr = curr.next;
}
return head;
}
static void printList(Node head) {
while (head != null) {
System.out.print(head.data);
if (head.next != null) {
System.out.print(" -> ");
}
head = head.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head = new Node(10);
head.next = new Node(4);
head.next.next = new Node(5);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(6);
head = modifyTheList(head);
printList(head);
}
}
class Node:
def __init__(self, data):
self.data = data
self.next = None
def modifyTheList(head):
values = []
# Store all node values
curr = head
while curr is not None:
values.append(curr.data)
curr = curr.next
left = 0
right = len(values) - 1
# Update paired values
while left < right:
value = values[left]
values[left] = values[right] - value
values[right] = value
left += 1
right -= 1
# Copy updated values back to the linked list
curr = head
for value in values:
curr.data = value
curr = curr.next
return head
def printList(head):
while head is not None:
print(head.data, end="")
if head.next is not None:
print(" -> ", end="")
head = head.next
print()
if __name__ == "__main__":
head = Node(10)
head.next = Node(4)
head.next.next = Node(5)
head.next.next.next = Node(3)
head.next.next.next.next = Node(6)
head = modifyTheList(head)
printList(head)
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
next = null;
}
}
class GFG {
static Node modifyTheList(Node head) {
List<int> values = new List<int>();
// Store all node values
for (Node curr = head; curr != null; curr = curr.next) {
values.Add(curr.data);
}
int left = 0;
int right = values.Count - 1;
// Update paired values
while (left < right) {
int value = values[left];
values[left] = values[right] - value;
values[right] = value;
left++;
right--;
}
// Copy updated values back to the linked list
Node current = head;
foreach (int value in values) {
current.data = value;
current = current.next;
}
return head;
}
static void PrintList(Node head) {
while (head != null) {
Console.Write(head.data);
if (head.next != null) {
Console.Write(" -> ");
}
head = head.next;
}
Console.WriteLine();
}
static void Main() {
Node head = new Node(10);
head.next = new Node(4);
head.next.next = new Node(5);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(6);
head = modifyTheList(head);
PrintList(head);
}
}
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
function modifyTheList(head) {
const values = [];
// Store all node values
let curr = head;
while (curr !== null) {
values.push(curr.data);
curr = curr.next;
}
let left = 0;
let right = values.length - 1;
// Update paired values
while (left < right) {
const value = values[left];
values[left] = values[right] - value;
values[right] = value;
left++;
right--;
}
// Copy updated values back to the linked list
curr = head;
for (const value of values) {
curr.data = value;
curr = curr.next;
}
return head;
}
function printList(head) {
let result = "";
while (head !== null) {
result += head.data;
if (head.next !== null) {
result += " -> ";
}
head = head.next;
}
console.log(result);
}
// Driver Code
let head = new Node(10);
head.next = new Node(4);
head.next.next = new Node(5);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(6);
head = modifyTheList(head);
printList(head);
Output
-4 -> -1 -> 5 -> 4 -> 10
[Expected Approach] Reverse the Second Half of the Linked List - O(n) Time and O(1) Space
The idea is to avoid using extra space by modifying the linked list directly. Find the middle of the list, reverse the second half, and process both halves simultaneously to update the paired nodes. Finally, reverse the second half again to restore the original structure of the linked list.
Working of Approach:
- Use slow and fast pointers to find the middle of the linked list.
- Reverse the second half of the linked list.
- Traverse the first half and the reversed second half together, updating the node values according to the given rules.
- Reverse the second half again and reconnect it to restore the original list structure.
- Return the head of the modified linked list.
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int x) {
data = x;
next = nullptr;
}
};
Node* reverse(Node* head) {
Node* prev = nullptr;
Node* curr = head;
while (curr != nullptr) {
Node* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
Node* modifyTheList(Node* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
Node* slow = head;
Node* fast = head;
// Find the middle of the linked list
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
Node* secondHalf = slow->next;
slow->next = nullptr;
// Reverse the second half
secondHalf = reverse(secondHalf);
Node* first = head;
Node* second = secondHalf;
// Modify paired node values
while (second != nullptr) {
int value = first->data;
first->data = second->data - value;
second->data = value;
first = first->next;
second = second->next;
}
// Restore the original structure
slow->next = reverse(secondHalf);
return head;
}
void printList(Node* head) {
while (head != nullptr) {
cout << head->data;
if (head->next != nullptr) {
cout << " -> ";
}
head = head->next;
}
cout << endl;
}
int main() {
Node* head = new Node(10);
head->next = new Node(4);
head->next->next = new Node(5);
head->next->next->next = new Node(3);
head->next->next->next->next = new Node(6);
head = modifyTheList(head);
printList(head);
return 0;
}
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
}
}
class GFG {
static Node reverse(Node head) {
Node prev = null;
Node curr = head;
while (curr != null) {
Node next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
static Node modifyTheList(Node head) {
if (head == null || head.next == null) {
return head;
}
Node slow = head;
Node fast = head;
// Find the middle of the linked list
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
Node secondHalf = slow.next;
slow.next = null;
// Reverse the second half
secondHalf = reverse(secondHalf);
Node first = head;
Node second = secondHalf;
// Modify paired node values
while (second != null) {
int value = first.data;
first.data = second.data - value;
second.data = value;
first = first.next;
second = second.next;
}
// Restore the original structure
slow.next = reverse(secondHalf);
return head;
}
static void printList(Node head) {
while (head != null) {
System.out.print(head.data);
if (head.next != null) {
System.out.print(" -> ");
}
head = head.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head = new Node(10);
head.next = new Node(4);
head.next.next = new Node(5);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(6);
head = modifyTheList(head);
printList(head);
}
}
class Node:
def __init__(self, data):
self.data = data
self.next = None
def reverse(head):
prev = None
curr = head
while curr is not None:
next = curr.next
curr.next = prev
prev = curr
curr = next
return prev
def modifyTheList(head):
if head is None or head.next is None:
return head
slow = head
fast = head
# Find the middle of the linked list
while fast.next is not None and fast.next.next is not None:
slow = slow.next
fast = fast.next.next
secondHalf = slow.next
slow.next = None
# Reverse the second half
secondHalf = reverse(secondHalf)
first = head
second = secondHalf
# Modify paired node values
while second is not None:
value = first.data
first.data = second.data - value
second.data = value
first = first.next
second = second.next
# Restore the original structure
slow.next = reverse(secondHalf)
return head
def printList(head):
while head is not None:
print(head.data, end="")
if head.next is not None:
print(" -> ", end="")
head = head.next
print()
if __name__ == "__main__":
head = Node(10)
head.next = Node(4)
head.next.next = Node(5)
head.next.next.next = Node(3)
head.next.next.next.next = Node(6)
head = modifyTheList(head)
printList(head)
using System;
class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
next = null;
}
}
class GFG {
static Node Reverse(Node head) {
Node prev = null;
Node curr = head;
while (curr != null) {
Node next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
static Node modifyTheList(Node head) {
if (head == null || head.next == null) {
return head;
}
Node slow = head;
Node fast = head;
// Find the middle of the linked list
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
Node secondHalf = slow.next;
slow.next = null;
// Reverse the second half
secondHalf = Reverse(secondHalf);
Node first = head;
Node second = secondHalf;
// Modify paired node values
while (second != null) {
int value = first.data;
first.data = second.data - value;
second.data = value;
first = first.next;
second = second.next;
}
// Restore the original structure
slow.next = Reverse(secondHalf);
return head;
}
static void PrintList(Node head) {
while (head != null) {
Console.Write(head.data);
if (head.next != null) {
Console.Write(" -> ");
}
head = head.next;
}
Console.WriteLine();
}
static void Main() {
Node head = new Node(10);
head.next = new Node(4);
head.next.next = new Node(5);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(6);
head = modifyTheList(head);
PrintList(head);
}
}
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
function reverse(head) {
let prev = null;
let curr = head;
while (curr !== null) {
let next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
function modifyTheList(head) {
if (head === null || head.next === null) {
return head;
}
let slow = head;
let fast = head;
// Find the middle of the linked list
while (fast.next !== null && fast.next.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
let secondHalf = slow.next;
slow.next = null;
// Reverse the second half
secondHalf = reverse(secondHalf);
let first = head;
let second = secondHalf;
// Modify paired node values
while (second !== null) {
let value = first.data;
first.data = second.data - value;
second.data = value;
first = first.next;
second = second.next;
}
// Restore the original structure
slow.next = reverse(secondHalf);
return head;
}
function printList(head) {
let result = "";
while (head !== null) {
result += head.data;
if (head.next !== null) {
result += " -> ";
}
head = head.next;
}
console.log(result);
}
// Driver Code
let head = new Node(10);
head.next = new Node(4);
head.next.next = new Node(5);
head.next.next.next = new Node(3);
head.next.next.next.next = new Node(6);
head = modifyTheList(head);
printList(head);
Output
-4 -> -1 -> 5 -> 4 -> 10
