Given a linked list where every node represents a linked list and contains two pointers of its type:
- Pointer to next node in the main list (we call it ‘right’ pointer in the below code)
- Pointer to a linked list where this node is head (we call it ‘down’ pointer in the below code).
All linked lists are sorted. See the following example
Examples:
Input: 5 -> 10 -> 19 -> 28 | | | | V V V V 7 20 22 35 | | | V V V 8 50 40 | | V V 30 45 Output: 5->7->8->10->19->20->22->28->30->35->40->45->50 Input: 5 -> 10 -> 19 -> 28 | | V V 7 22 | | V V 8 50 | V 30 Output: 5->7->8->10->19->20->22->30->50
In the previous post, we have to use the merge() process of merge sort for linked lists to flatten the linked list.
In this post, we will solve it using Heap.
Approach: The idea is to observe that from each top node there are N nodes that are connected in a downward direction but observe that all the downward nodes are in sorted order. So the task is to sort this entire thing in increasing order(or decreasing order).
- Push the head of all the linked lists in the downward list in the priority queue.
- Pop the smallest node from the priority queue.
- Check the location of the node so that the next node pointed by the current node can be pushed into the priority queue.
- Again pop out the smallest element and insert the next node pointed by the current node till the heap becomes empty.
- Keep on adding the data of nodes in a new linked list that are popped out to the new list.
- Print the linked list formed above.
Below is the implementation of the above approach:
C++
// C++ program for Flattening // a linked list using Heaps #include <bits/stdc++.h> using namespace std; // Structure of given Linked list struct Node { int data; struct Node* right; struct Node* down; Node( int x) { data = x; right = NULL; down = NULL; } }; // Function to print the // linked list void printList(Node* Node) { while (Node != NULL) { printf ( "%d " , Node->data); Node = Node->down; } } // Function that compares the value // pointed by node and returns true // if first data is greater struct compare { bool operator()(Node* a, Node* b) { return a->data > b->data; } }; // Function which returns the root // of the flattened linked list Node* flatten(Node* root) { Node* ptr = root; Node* head = NULL; // Min Heap which will return // smallest element currently // present in heap priority_queue<Node*, vector<Node*>, compare> pq; // Push the head nodes of each // downward linked list while (ptr != NULL) { pq.push(ptr); ptr = ptr->right; } // This loop will execute // till the map becomes empty while (!pq.empty()) { // Pop out the node that // contains element // currently in heap Node* temp = pq.top(); pq.pop(); // Push the next node pointed by // the current node into heap // if it is not null if (temp->down != NULL) { pq.push(temp->down); } // Create new linked list // that is to be returned if (head == NULL) { head = temp; ptr = temp; ptr->right = NULL; } else { ptr->down = temp; ptr = temp; ptr->right = NULL; } } // Pointer to head node // in the linked list return head; } // Create and push new nodes void push(Node** head_ref, int new_data) { Node* new_node = (Node*) malloc ( sizeof (Node)); new_node->right = NULL; new_node->data = new_data; new_node->down = (*head_ref); (*head_ref) = new_node; } // Driver Code int main() { Node* root = NULL; // Given Linked List push(&root, 30); push(&root, 8); push(&root, 7); push(&root, 5); push(&(root->right), 20); push(&(root->right), 10); push(&(root->right->right), 50); push(&(root->right->right), 22); push(&(root->right->right), 19); push(&(root->right->right->right), 45); push(&(root->right->right->right), 40); push(&(root->right->right->right), 35); push(&(root->right->right->right), 20); // Flatten the list root = flatten(root); // Print the flattened linked list printList(root); return 0; } |
Java
// Java program for Flattening // a linked list using Heaps import java.util.*; // Linked list Node class Node { int data; Node right, down; Node( int data) { this .data = data; right = null ; down = null ; } } class pair { int val; Node head; pair(Node head, int val) { this .val = val; this .head = head; } } // Class that compares the value // pointed by node and make // LinkedList sorted class pairComp implements Comparator<pair> { public int compare(pair p1, pair p2) { return p1.val - p2.val; } } class GFG { // Function which returns the root // of the flattened linked list public static Node flatten(Node root) { Node ptr = root; Node h = null ; // Min Heap which will return // smallest element currently // present in heap PriorityQueue<pair> pq = new PriorityQueue<pair>( new pairComp()); // Push the head nodes of each // downward linked list while (ptr != null ) { pq.add( new pair(ptr, ptr.data)); ptr = ptr.right; } // This loop will execute // till the pq becomes empty while (!pq.isEmpty()) { // Pop out the node that // contains element // currently in heap Node temp = pq.poll().head; // Push the next node pointed by // the current node into heap // if it is not null if (temp.down != null ) { pq.add( new pair(temp.down, temp.down.data)); } // Create new linked list // that is to be returned if (h == null ) { h = temp; ptr = temp; ptr.right = null ; } else { ptr.down = temp; ptr = temp; ptr.right = null ; } } // Pointer to head node // in the linked list return h; } // Create and push new nodes public static Node push(Node head_ref, int data) { // Allocate the Node & // Put in the data Node new_node = new Node(data); // Make next of new Node as head new_node.down = head_ref; // Move the head to point to new Node head_ref = new_node; // return to link it back return head_ref; } // Function to print the // linked list public static void printList(Node h) { while (h != null ) { System.out.print(h.data + " " ); h = h.down; } } // Driver code public static void main(String args[]) { Node head = null ; head = push(head, 30 ); head = push(head, 8 ); head = push(head, 7 ); head = push(head, 5 ); head.right = push(head.right, 20 ); head.right = push(head.right, 10 ); head.right.right = push( head.right.right, 50 ); head.right.right = push( head.right.right, 22 ); head.right.right = push( head.right.right, 19 ); head.right.right.right = push( head.right.right.right, 45 ); head.right.right.right = push( head.right.right.right, 40 ); head.right.right.right = push( head.right.right.right, 35 ); head.right.right.right = push(head.right.right.right, 20 ); // Flatten the list head = flatten(head); printList(head); } } // This code is contributed by Naresh Saharan // and Sagar Jangra and Tridib Samanta |
Python3
import heapq # Linked list Node class Node: def __init__( self , data): self .data = data self .right = None self .down = None class pair: def __init__( self , head, val): self .val = val self .head = head def __lt__( self , other): return self .val < other.val # Class that compares the value # pointed by node and make # LinkedList sorted class pairComp: def __lt__( self , p1, p2): return p1.val < p2.val # Function which returns the root # of the flattened linked list def flatten(root): ptr = root h = None # Min Heap which will return # smallest element currently # present in heap pq = [] # Push the head nodes of each # downward linked list while ptr: heapq.heappush(pq, pair(ptr, ptr.data)) ptr = ptr.right # This loop will execute # till the pq becomes empty while pq: # Pop out the node that # contains element # currently in heap temp = heapq.heappop(pq).head # Push the next node pointed by # the current node into heap # if it is not null if temp.down: heapq.heappush(pq, pair(temp.down, temp.down.data)) # Create new linked list # that is to be returned if not h: h = temp ptr = temp ptr.right = None else : ptr.down = temp ptr = temp ptr.right = None # Pointer to head node # in the linked list return h # Create and push new nodes def push(head_ref, data): # Allocate the Node & # Put in the data new_node = Node(data) # Make next of new Node as head new_node.down = head_ref # Move the head to point to new Node head_ref = new_node # return to link it back return head_ref # Function to print the # linked list def printList(h): while h: print (h.data, end = ' ' ) h = h.down # Driver code head = None head = push(head, 30 ) head = push(head, 8 ) head = push(head, 7 ) head = push(head, 5 ) head.right = push(head.right, 20 ) head.right = push(head.right, 10 ) head.right.right = push(head.right.right, 50 ) head.right.right = push(head.right.right, 22 ) head.right.right = push(head.right.right, 19 ) head.right.right.right = push(head.right.right.right, 45 ) head.right.right.right = push(head.right.right.right, 40 ) head.right.right.right = push(head.right.right.right, 35 ) head.right.right.right = push(head.right.right.right, 20 ) # Flatten the list head = flatten(head) printList(head) |
Javascript
// JavaScript program for Flattening // a linked list using Heaps // Linked list Node class Node { constructor(data) { this .data = data; this .right = null ; this .down = null ; } } class Pair { constructor(head, val) { this .val = val; this .head = head; } // Compare the value // pointed by node and make // LinkedList sorted static compare(p1, p2) { return p1.val - p2.val; } } // Function which returns the root // of the flattened linked list function flatten(root) { let ptr = root; let h = null ; // Array which will return // smallest element currently // present in heap const pq = []; // Push the head nodes of each // downward linked list while (ptr) { pq.push( new Pair(ptr, ptr.data)); ptr = ptr.right; } // This loop will execute // till the pq becomes empty while (pq.length > 0) { // Pop out the node that // contains element // currently in heap const temp = pq.sort(Pair.compare).shift().head; // Push the next node pointed by // the current node into heap // if it is not null if (temp.down) { pq.push( new Pair(temp.down, temp.down.data)); } // Create new linked list // that is to be returned if (!h) { h = temp; ptr = temp; ptr.right = null ; } else { ptr.down = temp; ptr = temp; ptr.right = null ; } } // Pointer to head node // in the linked list return h; } // Create and push new nodes function push(head_ref, data) { // Allocate the Node & // Put in the data const new_node = new Node(data); // Make next of new Node as head new_node.down = head_ref; // Move the head to point to new Node head_ref = new_node; // return to link it back return head_ref; } // Function to print the // linked list function printList(h) { let temp = []; while (h) { temp.push(h.data, ' ' ); h = h.down; } console.log(temp.join( '' )); } // Driver code let head = null ; head = push(head, 30); head = push(head, 8); head = push(head, 7); head = push(head, 5); head.right = push(head.right, 20); head.right = push(head.right, 10); head.right.right = push(head.right.right, 50); head.right.right = push(head.right.right, 22); head.right.right = push(head.right.right, 19); head.right.right.right = push(head.right.right.right, 45); head.right.right.right = push(head.right.right.right, 40); head.right.right.right = push(head.right.right.right, 35); head.right.right.right = push(head.right.right.right, 20); // Flatten the list head = flatten(head); printList(head); // Contributed by sdeadityasharma |
5 7 8 10 19 20 20 22 30 35 40 45 50
Time Complexity: O(k * log k) + O((N-k) * log k) = O(N * log k), where ‘k‘ is the number of nodes in the topmost horizontal linked list and ‘N‘ is the total number of nodes among all the linked lists. ‘log k‘ time is taken for the min-heapify procedure.
Auxiliary Space: O(k) for the min-heap, where ‘k‘ is the number of nodes in the topmost horizontal linked list. The min-heap will have at the most ‘k‘ number of nodes at any time.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!