Given a non-decreasing linked list. The task is to square the elements of the linked list and arrange them in sorted order without using any extra space.
Examples:
Input: 1->2->3->4->5
Output: 1->4->9->16->25Input: (-2) -> (-1) -> 0 -> 1 -> 2
Output: 0 ->1 -> 1 -> 4 -> 4
For Arrays: The problem to do the same for Arrays is discussed in this article – Sort array after converting elements to their squares
Approach: The task can be solved by partitioning the given list into two different linked lists from the point of transition (negative to positive), one containing only negative elements say ‘l1‘ and the other containing positive elements say ‘l2‘. Square all the elements of the list l1 and reverse it and also square all the elements of list l2, now merge the two sorted lists to get the resultant list.
Below is the implementation of the above approach :
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
struct Node {
int data;
Node* next;
Node( int data)
{
this ->data = data;
this ->next = NULL;
}
}; // Utility function to make linked list Node* makeList( int n, int arr[])
{ Node* h = NULL;
Node* root;
for ( int i = 0; i < n; i++) {
int data = arr[i];
Node* node = new Node(data);
if (h == NULL) {
h = node;
root = h;
}
else {
root->next = node;
root = node;
}
}
return h;
} // Utility function to print list void print_list(Node* head)
{ while (head != NULL) {
cout << head->data << " " ;
head = head->next;
}
cout << "\n" ;
} // Function to reverse the linked list Node* reverse(Node* head) { // Initialize current, previous and
// next pointers
Node* current = head;
Node *prev = NULL, *next = NULL;
while (current != NULL) {
// Store next
next = current->next;
// Reverse current node's pointer
current->next = prev;
// Move pointers one position ahead.
prev = current;
current = next;
}
head = prev;
return head;
} // This function will find the point of transition // where elements switch from negative to positive // and return that point Node* findBreakPoint(Node* head) { if (head == NULL) {
return NULL;
}
Node *prev = NULL, *curr = head;
while (curr != NULL) {
prev = curr;
curr = curr->next;
if (curr != NULL) {
// If prev element is negative and
// current element is positive
if ((prev->data) < 0
and (curr->data) >= 0) {
return prev;
}
}
}
// Checking if list contains
// only negative elements
curr = head;
while (curr->next) {
if (curr->data < 0) {
curr = curr->next;
continue ;
}
else {
// Contains positive elements
return NULL;
}
}
// Contains only negative element
// so returning the last element of the list
return curr;
} // Utility function to merge two sorted lists struct Node* mergeUtil( struct Node* h1,
struct Node* h2)
{ // If only one node in first list
// simply point its head to second list
if (!h1->next) {
h1->next = h2;
return h1;
}
// Initialize current and next pointers of
// both lists
struct Node *curr1 = h1, *next1 = h1->next;
struct Node *curr2 = h2, *next2 = h2->next;
while (next1 && curr2) {
// If curr2 lies in between
// curr1 and next1
// then do curr1->curr2->next1
if ((curr2->data) >= (curr1->data)
&& (curr2->data) <= (next1->data)) {
next2 = curr2->next;
curr1->next = curr2;
curr2->next = next1;
// Let curr1 and curr2 to point
// their immediate next pointers
curr1 = curr2;
curr2 = next2;
}
else {
// If more nodes in first list
if (next1->next) {
next1 = next1->next;
curr1 = curr1->next;
}
// Else point the last
// node of first list
// to the remaining
// nodes of second list
else {
next1->next = curr2;
return h1;
}
}
}
return h1;
} // Merges two given lists in-place. // This function mainly compares // head nodes and calls mergeUtil() struct Node* merge( struct Node* h1,
struct Node* h2)
{ if (!h1)
return h2;
if (!h2)
return h1;
// Start with the linked list
// whose head data is the least
if (h1->data < h2->data)
return mergeUtil(h1, h2);
else
return mergeUtil(h2, h1);
} // Function to return resultant squared list Node* squaresList(Node* head) { if (head == NULL)
return NULL;
Node* mid = findBreakPoint(head);
Node* temp = head;
while (temp != NULL) {
temp->data *= temp->data;
temp = temp->next;
}
// List contains only positive elements
if (mid == NULL) {
return head;
}
// List contains both positive
// and negative elements
Node* h1 = head;
Node* h2 = mid->next;
// Breaking the list where negative
// switches to positive
mid->next = NULL;
// Reversing the list
h1 = reverse(h1);
// Merging the two lists
Node* ans = merge(h1, h2);
return ans;
} // Driver Program int main()
{ int n = 7;
int arr1[] = { 1, 2, 3, 4, 5 };
Node* head = makeList( sizeof (arr1)
/ sizeof ( int ),
arr1);
n = 6;
int arr2[] = { -2, -1, 0, 1, 2 };
head = makeList( sizeof (arr2)
/ sizeof ( int ),
arr2);
int arr3[] = { -5, -4, -3, -2, -1 };
head = makeList( sizeof (arr3)
/ sizeof ( int ),
arr3);
print_list(squaresList(head));
} |
// Java program for the above approach import java.util.*;
public class GFG{
public static class Node {
int data;
Node next;
Node( int data)
{
this .data = data;
this .next = null ;
}
public Node() {
// TODO Auto-generated constructor stub
}
}; // Utility function to make linked list static Node makeList( int n, int arr[])
{ Node h = null ;
Node root = new Node();
for ( int i = 0 ; i < n; i++) {
int data = arr[i];
Node node = new Node(data);
if (h == null ) {
h = node;
root = h;
}
else {
root.next = node;
root = node;
}
}
return h;
} // Utility function to print list static void print_list(Node head)
{ while (head != null ) {
System.out.print(head.data+ " " );
head = head.next;
}
System.out.print( "\n" );
} // Function to reverse the linked list static Node reverse(Node head)
{ // Initialize current, previous and
// next pointers
Node current = head;
Node prev = null , next = null ;
while (current != null ) {
// Store next
next = current.next;
// Reverse current node's pointer
current.next = prev;
// Move pointers one position ahead.
prev = current;
current = next;
}
head = prev;
return head;
} // This function will find the point of transition // where elements switch from negative to positive // and return that point static Node findBreakPoint(Node head)
{ if (head == null ) {
return null ;
}
Node prev = null , curr = head;
while (curr != null ) {
prev = curr;
curr = curr.next;
if (curr != null ) {
// If prev element is negative and
// current element is positive
if ((prev.data) < 0
&& (curr.data) >= 0 ) {
return prev;
}
}
}
// Checking if list contains
// only negative elements
curr = head;
while (curr.next!= null ) {
if (curr.data < 0 ) {
curr = curr.next;
continue ;
}
else {
// Contains positive elements
return null ;
}
}
// Contains only negative element
// so returning the last element of the list
return curr;
} // Utility function to merge two sorted lists static Node mergeUtil(Node h1,
Node h2)
{ // If only one node in first list
// simply point its head to second list
if (h1.next!= null ) {
h1.next = h2;
return h1;
}
// Initialize current and next pointers of
// both lists
Node curr1 = h1, next1 = h1.next;
Node curr2 = h2, next2 = h2.next;
while (next1!= null && curr2!= null ) {
// If curr2 lies in between
// curr1 and next1
// then do curr1.curr2.next1
if ((curr2.data) >= (curr1.data)
&& (curr2.data) <= (next1.data)) {
next2 = curr2.next;
curr1.next = curr2;
curr2.next = next1;
// Let curr1 and curr2 to point
// their immediate next pointers
curr1 = curr2;
curr2 = next2;
}
else {
// If more nodes in first list
if (next1.next!= null ) {
next1 = next1.next;
curr1 = curr1.next;
}
// Else point the last
// node of first list
// to the remaining
// nodes of second list
else {
next1.next = curr2;
return h1;
}
}
}
return h1;
} // Merges two given lists in-place. // This function mainly compares // head nodes and calls mergeUtil() static Node merge(Node h1,
Node h2)
{ if (h1== null )
return h2;
if (h2== null )
return h1;
// Start with the linked list
// whose head data is the least
if (h1.data < h2.data)
return mergeUtil(h1, h2);
else
return mergeUtil(h2, h1);
} // Function to return resultant squared list static Node squaresList(Node head)
{ if (head == null )
return null ;
Node mid = findBreakPoint(head);
Node temp = head;
while (temp != null ) {
temp.data *= temp.data;
temp = temp.next;
}
// List contains only positive elements
if (mid == null ) {
return head;
}
// List contains both positive
// and negative elements
Node h1 = head;
Node h2 = mid.next;
// Breaking the list where negative
// switches to positive
mid.next = null ;
// Reversing the list
h1 = reverse(h1);
// Merging the two lists
Node ans = merge(h1, h2);
return ans;
} // Driver Program public static void main(String[] args)
{ int n = 7 ;
int arr1[] = { 1 , 2 , 3 , 4 , 5 };
Node head = makeList(arr1.length,
arr1);
n = 6 ;
int arr2[] = { - 2 , - 1 , 0 , 1 , 2 };
head = makeList(arr2.length,
arr2);
int arr3[] = { - 5 , - 4 , - 3 , - 2 , - 1 };
head = makeList(arr3.length,
arr3);
print_list(squaresList(head));
} } // This code is contributed by 29AjayKumar |
# Python program to implement # the above approach class Node:
def __init__( self , data = None , next = None ):
self .data = data
self . next = next
def make_list(n, arr):
if n = = 0 :
return None
head = Node(arr[ 0 ])
curr = head
for i in range ( 1 , n):
curr. next = Node(arr[i])
curr = curr. next
return head
# Utility function to print list def print_list(head):
while head is not None :
print (head.data, end = " " )
head = head. next
print ()
# Function to reverse the linked list def reverse(head):
# Initialize current, previous and next pointers
current = head
prev = None
next = None
while current is not None :
# Store next
next = current. next
# Reverse current node's pointer
current. next = prev
# Move pointers one position ahead.
prev = current
current = next
head = prev
return head
# This function will find the point of transition # where elements switch from negative to positive # and return that point def find_break_point(head):
if head is None :
return None
prev = None
curr = head
while curr is not None :
prev = curr
curr = curr. next
if curr is not None :
# If prev element is negative and
# current element is positive
if (prev.data < 0 and curr.data > = 0 ):
return prev
# Checking if list contains
# only negative elements
curr = head
while curr. next :
if curr.data < 0 :
curr = curr. next
continue
else :
# Contains positive elements
return None
# Contains only negative element
# so returning the last element of the list
return curr
# Utility function to merge two sorted lists def mergeUtil(h1, h2):
# If only one node in first list
# simply point its head to second list
if not h1. next :
h1. next = h2
return h1
# Initialize current and next pointers of
# both lists
curr1 = h1
next1 = h1. next
curr2 = h2
next2 = h2. next
while next1 and curr2:
# If curr2 lies in between
# curr1 and next1
# then do curr1.curr2.next1
if curr2.data > = curr1.data and curr2.data < = next1.data:
next2 = curr2. next
curr1. next = curr2
curr2. next = next1
# Let curr1 and curr2 to point
# their immediate next pointers
curr1 = curr2
curr2 = next2
else :
# If more nodes in first list
if next1. next :
next1 = next1. next
curr1 = curr1. next
# Else point the last
# node of first list
# to the remaining
# nodes of second list
else :
next1. next = curr2
return h1
return h1
# Merges two given lists in-place. # This function mainly compares # head nodes and calls merge_util() def merge(h1, h2):
if not h1:
return h2
if not h2:
return h1
# Start with the linked list
# whose head data is the least
if h1.data < h2.data:
return merge_util(h1, h2)
else :
return merge_util(h2, h1)
# Function to return resultant squared list def squares_list(head):
if not head:
return None
mid = find_break_point(head)
temp = head
while temp:
temp.data * = temp.data
temp = temp. next
# List contains only positive elements
if not mid:
return head
# List contains both positive
# and negative elements
h1 = head
h2 = mid. next
# Breaking the list where negative
# switches to positive
mid. next = None
# Reversing the list
h1 = reverse(h1)
# Merging the two lists
ans = merge(h1, h2)
return ans
# Driver Program n = 7
arr1 = [ 1 , 2 , 3 , 4 , 5 ]
head = make_list( len (arr1), arr1)
n = 6
arr2 = [ - 2 , - 1 , 0 , 1 , 2 ]
head = make_list( len (arr2), arr2)
arr3 = [ - 5 , - 4 , - 3 , - 2 , - 1 ]
head = make_list( len (arr3), arr3)
print_list(squares_list(head)) |
// C# program for the above approach using System;
public class GFG{
class Node {
public int data;
public Node next;
public Node( int data)
{
this .data = data;
this .next = null ;
}
public Node() {
// TODO Auto-generated constructor stub
}
}; // Utility function to make linked list static Node makeList( int n, int []arr)
{ Node h = null ;
Node root = new Node();
for ( int i = 0; i < n; i++) {
int data = arr[i];
Node node = new Node(data);
if (h == null ) {
h = node;
root = h;
}
else {
root.next = node;
root = node;
}
}
return h;
} // Utility function to print list static void print_list(Node head)
{ while (head != null ) {
Console.Write(head.data+ " " );
head = head.next;
}
Console.Write( "\n" );
} // Function to reverse the linked list static Node reverse(Node head)
{ // Initialize current, previous and
// next pointers
Node current = head;
Node prev = null , next = null ;
while (current != null ) {
// Store next
next = current.next;
// Reverse current node's pointer
current.next = prev;
// Move pointers one position ahead.
prev = current;
current = next;
}
head = prev;
return head;
} // This function will find the point of transition // where elements switch from negative to positive // and return that point static Node findBreakPoint(Node head)
{ if (head == null ) {
return null ;
}
Node prev = null , curr = head;
while (curr != null ) {
prev = curr;
curr = curr.next;
if (curr != null ) {
// If prev element is negative and
// current element is positive
if ((prev.data) < 0
&& (curr.data) >= 0) {
return prev;
}
}
}
// Checking if list contains
// only negative elements
curr = head;
while (curr.next!= null ) {
if (curr.data < 0) {
curr = curr.next;
continue ;
}
else {
// Contains positive elements
return null ;
}
}
// Contains only negative element
// so returning the last element of the list
return curr;
} // Utility function to merge two sorted lists static Node mergeUtil(Node h1,
Node h2)
{ // If only one node in first list
// simply point its head to second list
if (h1.next!= null ) {
h1.next = h2;
return h1;
}
// Initialize current and next pointers of
// both lists
Node curr1 = h1, next1 = h1.next;
Node curr2 = h2, next2 = h2.next;
while (next1!= null && curr2!= null ) {
// If curr2 lies in between
// curr1 and next1
// then do curr1.curr2.next1
if ((curr2.data) >= (curr1.data)
&& (curr2.data) <= (next1.data)) {
next2 = curr2.next;
curr1.next = curr2;
curr2.next = next1;
// Let curr1 and curr2 to point
// their immediate next pointers
curr1 = curr2;
curr2 = next2;
}
else {
// If more nodes in first list
if (next1.next!= null ) {
next1 = next1.next;
curr1 = curr1.next;
}
// Else point the last
// node of first list
// to the remaining
// nodes of second list
else {
next1.next = curr2;
return h1;
}
}
}
return h1;
} // Merges two given lists in-place. // This function mainly compares // head nodes and calls mergeUtil() static Node merge(Node h1,
Node h2)
{ if (h1== null )
return h2;
if (h2== null )
return h1;
// Start with the linked list
// whose head data is the least
if (h1.data < h2.data)
return mergeUtil(h1, h2);
else
return mergeUtil(h2, h1);
} // Function to return resultant squared list static Node squaresList(Node head)
{ if (head == null )
return null ;
Node mid = findBreakPoint(head);
Node temp = head;
while (temp != null ) {
temp.data *= temp.data;
temp = temp.next;
}
// List contains only positive elements
if (mid == null ) {
return head;
}
// List contains both positive
// and negative elements
Node h1 = head;
Node h2 = mid.next;
// Breaking the list where negative
// switches to positive
mid.next = null ;
// Reversing the list
h1 = reverse(h1);
// Merging the two lists
Node ans = merge(h1, h2);
return ans;
} // Driver Program public static void Main(String[] args)
{ int n = 7;
int []arr1 = { 1, 2, 3, 4, 5 };
Node head = makeList(arr1.Length,
arr1);
n = 6;
int []arr2 = { -2, -1, 0, 1, 2 };
head = makeList(arr2.Length,
arr2);
int []arr3 = { -5, -4, -3, -2, -1 };
head = makeList(arr3.Length,
arr3);
print_list(squaresList(head));
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript Program to implement
// the above approach
class Node {
constructor(data) {
this .data = data;
this .next = null ;
}
}
// Utility function to make linked list
function makeList(n, arr) {
let h = null ;
let root;
for (let i = 0; i < n; i++) {
let data = arr[i];
let node = new Node(data);
if (h == null ) {
h = node;
root = h;
}
else {
root.next = node;
root = node;
}
}
return h;
}
// Utility function to print list
function print_list(head) {
while (head != null ) {
document.write(head.data + " " )
head = head.next;
}
document.write( "<br>" )
}
// Function to reverse the linked list
function reverse(head)
{
// Initialize current, previous and
// next pointers
let current = head;
let prev = null , next = null ;
while (current != null ) {
// Store next
next = current.next;
// Reverse current node's pointer
current.next = prev;
// Move pointers one position ahead.
prev = current;
current = next;
}
head = prev;
return head;
}
// This function will find the point of transition
// where elements switch from negative to positive
// and return that point
function findBreakPoint(head) {
if (head == null ) {
return null ;
}
let prev = null , curr = head;
while (curr != null ) {
prev = curr;
curr = curr.next;
if (curr != null ) {
// If prev element is negative and
// current element is positive
if ((prev.data) < 0
&& (curr.data) >= 0) {
return prev;
}
}
}
// Checking if list contains
// only negative elements
curr = head;
while (curr.next) {
if (curr.data < 0) {
curr = curr.next;
continue ;
}
else {
// Contains positive elements
return null ;
}
}
// Contains only negative element
// so returning the last element of the list
return curr;
}
// Utility function to merge two sorted lists
function mergeUtil(h1,
h2) {
// If only one node in first list
// simply point its head to second list
if (!h1.next) {
h1.next = h2;
return h1;
}
// Initialize current and next pointers of
// both lists
let curr1 = h1, next1 = h1.next;
let curr2 = h2, next2 = h2.next;
while (next1 && curr2) {
// If curr2 lies in between
// curr1 and next1
// then do curr1.curr2.next1
if ((curr2.data) >= (curr1.data)
&& (curr2.data) <= (next1.data)) {
next2 = curr2.next;
curr1.next = curr2;
curr2.next = next1;
// Let curr1 and curr2 to point
// their immediate next pointers
curr1 = curr2;
curr2 = next2;
}
else {
// If more nodes in first list
if (next1.next) {
next1 = next1.next;
curr1 = curr1.next;
}
// Else point the last
// node of first list
// to the remaining
// nodes of second list
else {
next1.next = curr2;
return h1;
}
}
}
return h1;
}
// Merges two given lists in-place.
// This function mainly compares
// head nodes and calls mergeUtil()
function merge(h1,
h2) {
if (!h1)
return h2;
if (!h2)
return h1;
// Start with the linked list
// whose head data is the least
if (h1.data < h2.data)
return mergeUtil(h1, h2);
else
return mergeUtil(h2, h1);
}
// Function to return resultant squared list
function squaresList(head) {
if (head == null )
return null ;
let mid = findBreakPoint(head);
let temp = head;
while (temp != null ) {
temp.data *= temp.data;
temp = temp.next;
}
// List contains only positive elements
if (mid == null ) {
return head;
}
// List contains both positive
// and negative elements
let h1 = head;
let h2 = mid.next;
// Breaking the list where negative
// switches to positive
mid.next = null ;
// Reversing the list
h1 = reverse(h1);
// Merging the two lists
let ans = merge(h1, h2);
return ans;
}
// Driver Program
let n = 7;
let arr1 = [1, 2, 3, 4, 5];
let head = makeList(arr1.length, arr1);
n = 6;
let arr2 = [-2, -1, 0, 1, 2];
head = makeList(arr2.length,
arr2);
let arr3 = [-5, -4, -3, -2, -1];
head = makeList(arr3.length,
arr3);
print_list(squaresList(head));
// This code is contributed by Potta Lokesh
</script>
|
1 4 9 16 25
Time complexity: O(N), N is the number of nodes
Auxiliary space: O(1)