Divyansh, while attending Geeks Classes, aims to solve all weekly contest problems. However, due to wrong submissions, he sometimes receives penalties, and each penalty reduces his score for that question by 10%. He requested the GeeksClasses team to provide all his contest scores as a linked list. The linked list is given as an array arr[], with each element representing a node.
The team now wants him to maximize this list based on specific rules:
- If two consecutive equal values appear just before a 100, then the second value is increased by 10% (floor value), and the first value is converted to 100.
- After applying all such updates, all nodes with value 100 must be moved to the end of the list, strictly by rearranging pointers (no new node creation).
Our task is to modify the linked list according to these rules and return the final updated list.
Example:
Input: arr[] = [75, 59, 84, 84, 100, 90]
Output: 75 -> 59 -> 92 -> 90 -> 100 -> 100
Explanation: The two equal numbers 84 and 84 appear just before 100, so the first 84 becomes 100 and the second becomes 84 + 10% = 92. After processing, all 100s are moved to the end, giving the final list: 75 -> 59 -> 92 -> 90 ->100 ->100.
Input: arr[] = [40, 70, 70, 100, 55, 55, 100, 80]
Output: 40 -> 70 -> 77 -> 55 -> 60 -> 80 -> 100 -> 100
Explanation: In the array, the consecutive values 70 and 70 appear just before a 100. Following the rules, the first 70 remains, and the second 70 is increased by 10% (floor value), becoming 77. Similarly, the consecutive 55 and 55 before a 100 are processed: the first 55 remains, and the second 55 becomes 60. After applying all updates, all nodes with value 100 are moved to the end of the list by rearranging pointers.
[Naive Approach] Full Scan and Fix - O(n^2) Time and O(1) Space
We scan the entire list again and again by looking for two equal numbers that come right before 100. If we find such a pair, we will change the first number to 100 and increase the second number by 10% (floor value). After applying this in entire linked list we make one final pass to move all 100s to the end by adjusting pointers.
C++
#include <iostream>
#include <vector>
using namespace std;
// Node structure for Linked List
struct Node {
int data;
Node* next;
Node(int x) : data(x), next(nullptr) {}
};
// Apply the rule: if X -> X -> 100 appears, update values
void applyRule(Node* head) {
Node* p = head;
while (p && p->next && p->next->next) {
if (p->data == p->next->data && p->next->next->data == 100) {
// First X becomes 100
p->data = 100;
// Second X increases by 10% (floor)
p->next->data = p->next->data + (p->next->data / 10);
// Move pointer past the updated nodes
p = p->next->next;
} else {
p = p->next;
}
}
}
// Move all nodes with value 100 to the end
Node* moveHundreds(Node* head) {
Node* dummy = new Node(-1);
dummy->next = head;
Node* prev = dummy;
Node* curr = head;
Node* hundredHead = nullptr;
Node* hundredTail = nullptr;
while (curr) {
if (curr->data == 100) {
// Remove current 100 from list
prev->next = curr->next;
curr->next = nullptr;
// Append to 100s list
if (!hundredHead) {
hundredHead = hundredTail = curr;
} else {
hundredTail->next = curr;
hundredTail = curr;
}
curr = prev->next;
} else {
prev = curr;
curr = curr->next;
}
}
// Attach all 100s at the end
prev->next = hundredHead;
return dummy->next;
}
Node* maximizeScores(vector<int>& arr) {
if (arr.empty()) return nullptr;
// Build linked list from array
Node* head = new Node(arr[0]);
Node* temp = head;
for (size_t i = 1; i < arr.size(); i++) {
temp->next = new Node(arr[i]);
temp = temp->next;
}
// Apply the X -> X -> 100 rule
applyRule(head);
// Move all 100s to the end
return moveHundreds(head);
}
// Helper function to print linked list
void printList(Node* head) {
Node* temp = head;
while (temp) {
cout << temp->data;
if (temp->next) cout << " -> ";
temp = temp->next;
}
cout << endl;
}
int main() {
vector<int> arr = {75, 59, 84, 84, 100, 90};
Node* head = maximizeScores(arr);
printList(head);
return 0;
}
Java
import java.util.Arrays;
class Node {
int data;
Node next;
Node(int x) { data = x; next = null; }
}
public class GFG {
// Apply the rule: if X -> X -> 100 appears, update values
static void applyRule(Node head) {
Node p = head;
while (p != null && p.next != null && p.next.next != null) {
if (p.data == p.next.data && p.next.next.data == 100) {
// First X becomes 100
p.data = 100;
// Second X increases by 10% (floor)
p.next.data = p.next.data + (p.next.data / 10);
// Move pointer past the updated nodes
p = p.next.next;
} else {
p = p.next;
}
}
}
// Move all nodes with value 100 to the end
static Node moveHundreds(Node head) {
Node dummy = new Node(-1);
dummy.next = head;
Node prev = dummy;
Node curr = head;
Node hundredHead = null;
Node hundredTail = null;
while (curr != null) {
if (curr.data == 100) {
// Remove current 100 from list
prev.next = curr.next;
curr.next = null;
// Append to 100s list
if (hundredHead == null) {
hundredHead = hundredTail = curr;
} else {
hundredTail.next = curr;
hundredTail = curr;
}
curr = prev.next;
} else {
prev = curr;
curr = curr.next;
}
}
// Attach all 100s at the end
prev.next = hundredHead;
return dummy.next;
}
static Node maximizeScores(int[] arr) {
if (arr.length == 0) return null;
// Build linked list from array
Node head = new Node(arr[0]);
Node temp = head;
for (int i = 1; i < arr.length; i++) {
temp.next = new Node(arr[i]);
temp = temp.next;
}
// Apply the X -> X -> 100 rule
applyRule(head);
// Move all 100s to the end
return moveHundreds(head);
}
// Helper function to print linked list
static void printList(Node head) {
Node temp = head;
while (temp != null) {
System.out.print(temp.data);
if (temp.next != null) System.out.print(" -> ");
temp = temp.next;
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = {75, 59, 84, 84, 100, 90};
Node head = maximizeScores(arr);
printList(head);
}
}
Python
# Node structure for Linked List
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Apply the rule: if X -> X -> 100 appears, update values
def applyRule(head):
p = head
while p and p.next and p.next.next:
if p.data == p.next.data and p.next.next.data == 100:
# First X becomes 100
p.data = 100
# Second X increases by 10% (floor)
p.next.data = p.next.data + (p.next.data // 10)
# Move pointer past the updated nodes
p = p.next.next
else:
p = p.next
# Move all nodes with value 100 to the end
def moveHundreds(head):
dummy = Node(-1)
dummy.next = head
prev = dummy
curr = head
hundredHead = None
hundredTail = None
while curr:
if curr.data == 100:
# Remove current 100 from list
prev.next = curr.next
curr.next = None
# Append to 100s list
if hundredHead is None:
hundredHead = hundredTail = curr
else:
hundredTail.next = curr
hundredTail = curr
curr = prev.next
else:
prev = curr
curr = curr.next
# Attach all 100s at the end
prev.next = hundredHead
return dummy.next
def maximizeScores(arr):
if not arr:
return None
# Build linked list from array
head = Node(arr[0])
temp = head
for val in arr[1:]:
temp.next = Node(val)
temp = temp.next
# Apply the X -> X -> 100 rule
applyRule(head)
# Move all 100s to the end
return moveHundreds(head)
# Helper function to print linked list
def printList(head):
temp = head
res = []
while temp:
res.append(str(temp.data))
temp = temp.next
print(" -> ".join(res))
if __name__ == "__main__":
arr = [75, 59, 84, 84, 100, 90]
head = maximizeScores(arr)
printList(head)
C#
using System;
class Node {
public int data;
public Node next;
public Node(int x) { data = x; next = null; }
}
class Solution {
// Apply the rule: if X -> X -> 100 appears, update values
static void applyRule(Node head) {
Node p = head;
while (p != null && p.next != null && p.next.next != null) {
if (p.data == p.next.data && p.next.next.data == 100) {
// First X becomes 100
p.data = 100;
// Second X increases by 10% (floor)
p.next.data = p.next.data + (p.next.data / 10);
// Move pointer past the updated nodes
p = p.next.next;
} else {
p = p.next;
}
}
}
// Move all nodes with value 100 to the end
static Node moveHundreds(Node head) {
Node dummy = new Node(-1);
dummy.next = head;
Node prev = dummy;
Node curr = head;
Node hundredHead = null;
Node hundredTail = null;
while (curr != null) {
if (curr.data == 100) {
// Remove current 100 from list
prev.next = curr.next;
curr.next = null;
// Append to 100s list
if (hundredHead == null) {
hundredHead = hundredTail = curr;
} else {
hundredTail.next = curr;
hundredTail = curr;
}
curr = prev.next;
} else {
prev = curr;
curr = curr.next;
}
}
// Attach all 100s at the end
prev.next = hundredHead;
return dummy.next;
}
static Node maximizeScores(int[] arr) {
if (arr.Length == 0) return null;
// Build linked list from array
Node head = new Node(arr[0]);
Node temp = head;
for (int i = 1; i < arr.Length; i++) {
temp.next = new Node(arr[i]);
temp = temp.next;
}
// Apply the X -> X -> 100 rule
applyRule(head);
// Move all 100s to the end
return moveHundreds(head);
}
// Helper function to print linked list
static void printList(Node head) {
Node temp = head;
while (temp != null) {
Console.Write(temp.data);
if (temp.next != null) Console.Write(" -> ");
temp = temp.next;
}
Console.WriteLine();
}
static void Main() {
int[] arr = {75, 59, 84, 84, 100, 90};
Node head = maximizeScores(arr);
printList(head);
}
}
JavaScript
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
// Apply the rule: if X -> X -> 100 appears, update values
function applyRule(head) {
let p = head;
while (p && p.next && p.next.next) {
if (p.data === p.next.data && p.next.next.data === 100) {
// First X becomes 100
p.data = 100;
// Second X increases by 10% (floor)
p.next.data = p.next.data + Math.floor(p.next.data / 10);
// Move pointer past the updated nodes
p = p.next.next;
} else {
p = p.next;
}
}
}
// Move all nodes with value 100 to the end
function moveHundreds(head) {
let dummy = new Node(-1);
dummy.next = head;
let prev = dummy;
let curr = head;
let hundredHead = null;
let hundredTail = null;
while (curr) {
if (curr.data === 100) {
// Remove current 100 from list
prev.next = curr.next;
curr.next = null;
// Append to 100s list
if (!hundredHead) {
hundredHead = hundredTail = curr;
} else {
hundredTail.next = curr;
hundredTail = curr;
}
curr = prev.next;
} else {
prev = curr;
curr = curr.next;
}
}
// Attach all 100s at the end
prev.next = hundredHead;
return dummy.next;
}
function maximizeScores(arr) {
if (arr.length === 0) return null;
// Build linked list from array
let head = new Node(arr[0]);
let temp = head;
for (let i = 1; i < arr.length; i++) {
temp.next = new Node(arr[i]);
temp = temp.next;
}
// Apply the X -> X -> 100 rule
applyRule(head);
// Move all 100s to the end
return moveHundreds(head);
}
// Helper function to print linked list
function printList(head) {
let temp = head;
let res = [];
while (temp) {
res.push(temp.data);
temp = temp.next;
}
console.log(res.join(" -> "));
}
// Example
let arr = [75, 59, 84, 84, 100, 90];
let head = maximizeScores(arr);
printList(head);
Output75 -> 59 -> 92 -> 90 -> 100 -> 100
[Optimised Approach] Single Pass Linked List Adjustment - O(n) Time and O(1) Space
The ides is we traverse the linked list just once. Whenever we encounter two consecutive equal numbers immediately followed by a 100, we update the first number to 100 and increase the second number by 10% (taking the floor value). While doing this, we continue scanning the entire list to ensure every 100 is accounted for. After applying all updates, we move all nodes with the value 100 to the end of the linked list, strictly by rearranging the pointers, preserving the original relative order of the other elements.
C++
#include <iostream>
#include <vector>
using namespace std;
// Node structure for Linked List
struct Node {
int data;
Node* next;
Node(int x) : data(x), next(nullptr) {}
};
// Apply the rule: if X -> X -> 100 appears, update values
void applyRule(Node* head) {
Node* curr = head;
while (curr && curr->next && curr->next->next) {
if (curr->data == curr->next->data && curr->next->next->data == 100) {
// First X becomes 100
curr->data = 100;
// Second X increases by 10% (floor)
curr->next->data += curr->next->data / 10;
}
curr = curr->next;
}
}
// Move all nodes with value 100 to the end
Node* moveHundreds(Node* head) {
Node* dummy = new Node(-1);
dummy->next = head;
Node* prev = dummy;
Node* curr = head;
Node* hundredHead = nullptr;
Node* hundredTail = nullptr;
while (curr) {
if (curr->data == 100) {
// Remove 100 node
prev->next = curr->next;
curr->next = nullptr;
// Append to 100s list
if (!hundredHead) hundredHead = hundredTail = curr;
else { hundredTail->next = curr; hundredTail = curr; }
curr = prev->next;
} else {
prev = curr;
curr = curr->next;
}
}
// Attach 100s at the end
prev->next = hundredHead;
return dummy->next;
}
// Build linked list from array, apply rules, move 100s
Node* maximizeScores(vector<int>& arr) {
if (arr.empty()) return nullptr;
// Build linked list
Node* head = new Node(arr[0]);
Node* temp = head;
for (size_t i = 1; i < arr.size(); i++) {
temp->next = new Node(arr[i]);
temp = temp->next;
}
// Apply X -> X -> 100 rule
applyRule(head);
// Move all 100s to the end
return moveHundreds(head);
}
// Helper function to print linked list
void printList(Node* head) {
Node* temp = head;
while (temp) {
cout << temp->data;
if (temp->next) cout << " -> ";
temp = temp->next;
}
cout << endl;
}
int main() {
vector<int> arr = {75, 59, 84, 84, 100, 90};
Node* head = maximizeScores(arr);
printList(head);
return 0;
}
Java
import java.util.Arrays;
// Node structure for Linked List
class Node {
int data;
Node next;
Node(int x) { data = x; next = null; }
}
public class GFG {
// Apply the rule: if X -> X -> 100 appears, update values
static void applyRule(Node head) {
Node curr = head;
while (curr != null && curr.next != null && curr.next.next != null) {
if (curr.data == curr.next.data && curr.next.next.data == 100) {
// First X becomes 100
curr.data = 100;
// Second X increases by 10% (floor)
curr.next.data += curr.next.data / 10;
}
curr = curr.next;
}
}
// Move all nodes with value 100 to the end
static Node moveHundreds(Node head) {
Node dummy = new Node(-1);
dummy.next = head;
Node prev = dummy, curr = head;
Node hundredHead = null, hundredTail = null;
while (curr != null) {
if (curr.data == 100) {
prev.next = curr.next;
curr.next = null;
if (hundredHead == null) hundredHead = hundredTail = curr;
else { hundredTail.next = curr; hundredTail = curr; }
curr = prev.next;
} else {
prev = curr;
curr = curr.next;
}
}
prev.next = hundredHead;
return dummy.next;
}
// Build linked list from array, apply rules, move 100s
static Node maximizeScores(int[] arr) {
if (arr.length == 0) return null;
Node head = new Node(arr[0]);
Node temp = head;
for (int i = 1; i < arr.length; i++) {
temp.next = new Node(arr[i]);
temp = temp.next;
}
applyRule(head);
return moveHundreds(head);
}
// Helper function to print linked list
static void printList(Node head) {
Node temp = head;
while (temp != null) {
System.out.print(temp.data);
if (temp.next != null) System.out.print(" -> ");
temp = temp.next;
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = {75, 59, 84, 84, 100, 90};
Node head = maximizeScores(arr);
printList(head);
}
}
Python
# Node structure for Linked List
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Apply the rule: if X -> X -> 100 appears, update values
def applyRule(head):
curr = head
while curr and curr.next and curr.next.next:
if curr.data == curr.next.data and curr.next.next.data == 100:
# First X becomes 100
curr.data = 100
# Second X increases by 10% (floor)
curr.next.data += curr.next.data // 10
curr = curr.next
# Move all nodes with value 100 to the end
def moveHundreds(head):
dummy = Node(-1)
dummy.next = head
prev = dummy
curr = head
hundredHead = hundredTail = None
while curr:
if curr.data == 100:
prev.next = curr.next
curr.next = None
if not hundredHead:
hundredHead = hundredTail = curr
else:
hundredTail.next = curr
hundredTail = curr
curr = prev.next
else:
prev = curr
curr = curr.next
prev.next = hundredHead
return dummy.next
# Build linked list from array, apply rules, move 100s
def maximizeScores(arr):
if not arr:
return None
head = Node(arr[0])
temp = head
for val in arr[1:]:
temp.next = Node(val)
temp = temp.next
applyRule(head)
return moveHundreds(head)
# Helper function to print linked list
def printList(head):
temp = head
while temp:
print(temp.data, end="")
if temp.next:
print(" -> ", end="")
temp = temp.next
print()
if __name__ == "__main__":
arr = [75, 59, 84, 84, 100, 90]
head = maximizeScores(arr)
printList(head)
C#
using System;
using System.Collections.Generic;
// Node structure for Linked List
class Node {
public int data;
public Node next;
public Node(int x) { data = x; next = null; }
}
class GFG {
// Apply the rule: if X -> X -> 100 appears, update values
static void applyRule(Node head) {
Node curr = head;
while (curr != null && curr.next != null && curr.next.next != null) {
if (curr.data == curr.next.data && curr.next.next.data == 100) {
// First X becomes 100
curr.data = 100;
// Second X increases by 10% (floor)
curr.next.data += curr.next.data / 10;
}
curr = curr.next;
}
}
// Move all nodes with value 100 to the end
static Node moveHundreds(Node head) {
Node dummy = new Node(-1);
dummy.next = head;
Node prev = dummy, curr = head;
Node hundredHead = null, hundredTail = null;
while (curr != null) {
if (curr.data == 100) {
// Remove 100 node
prev.next = curr.next;
curr.next = null;
// Append to 100s list
if (hundredHead == null) hundredHead = hundredTail = curr;
else { hundredTail.next = curr; hundredTail = curr; }
curr = prev.next;
} else {
prev = curr;
curr = curr.next;
}
}
// Attach 100s at the end
prev.next = hundredHead;
return dummy.next;
}
// Build linked list from array, apply rules, move 100s
static Node maximizeScores(int[] arr) {
if (arr.Length == 0) return null;
Node head = new Node(arr[0]);
Node temp = head;
for (int i = 1; i < arr.Length; i++) {
temp.next = new Node(arr[i]);
temp = temp.next;
}
// Apply X -> X -> 100 rule
applyRule(head);
// Move all 100s to the end
return moveHundreds(head);
}
// Helper function to print linked list
static void printList(Node head) {
Node temp = head;
while (temp != null) {
Console.Write(temp.data);
if (temp.next != null) Console.Write(" -> ");
temp = temp.next;
}
Console.WriteLine();
}
static void Main() {
int[] arr = {75, 59, 84, 84, 100, 90};
Node head = maximizeScores(arr);
printList(head);
}
}
JavaScript
// Node structure for Linked List
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
// Apply the rule: if X -> X -> 100 appears, update values
function applyRule(head) {
let curr = head;
while (curr && curr.next && curr.next.next) {
if (curr.data === curr.next.data && curr.next.next.data === 100) {
// First X becomes 100
curr.data = 100;
// Second X increases by 10% (floor)
curr.next.data += Math.floor(curr.next.data / 10);
}
curr = curr.next;
}
}
// Move all nodes with value 100 to the end
function moveHundreds(head) {
let dummy = new Node(-1);
dummy.next = head;
let prev = dummy;
let curr = head;
let hundredHead = null;
let hundredTail = null;
while (curr) {
if (curr.data === 100) {
// Remove 100 node
prev.next = curr.next;
curr.next = null;
// Append to 100s list
if (!hundredHead) hundredHead = hundredTail = curr;
else { hundredTail.next = curr; hundredTail = curr; }
curr = prev.next;
} else {
prev = curr;
curr = curr.next;
}
}
// Attach 100s at the end
prev.next = hundredHead;
return dummy.next;
}
// Build linked list from array, apply rules, move 100s
function maximizeScores(arr) {
if (arr.length === 0) return null;
let head = new Node(arr[0]);
let temp = head;
for (let i = 1; i < arr.length; i++) {
temp.next = new Node(arr[i]);
temp = temp.next;
}
// Apply X -> X -> 100 rule
applyRule(head);
// Move all 100s to the end
return moveHundreds(head);
}
// Helper function to print linked list
function printList(head) {
let temp = head;
let res = [];
while (temp) {
res.push(temp.data);
temp = temp.next;
}
console.log(res.join(" -> "));
}
// Example usage
let arr = [75, 59, 84, 84, 100, 90];
let head = maximizeScores(arr);
printList(head);
Output75 -> 59 -> 92 -> 90 -> 100 -> 100
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem