 GeeksforGeeks App
Open App Browser
Continue

# Sort a linked list after converting elements to their squares

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

Input: (-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++

 `// C++ program for the above approach``#include ``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

 `// 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`

## Python3

 `# 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#

 `// 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`

## Javascript

 ``

Output

`1 4 9 16 25 `

Time complexity: O(N), N is the number of nodes
Auxiliary space: O(1)

My Personal Notes arrow_drop_up