Saturday, November 16, 2024
Google search engine
HomeData Modelling & AIMerge k sorted arrays | Set 1

Merge k sorted arrays | Set 1

Given K sorted arrays of size N each, merge them and print the sorted output.

Examples:

Input: K = 3, N = 4, arr = { {1, 3, 5, 7}, {2, 4, 6, 8}, {0, 9, 10, 11}}
Output: 0 1 2 3 4 5 6 7 8 9 10 11 
Explanation: The output array is a sorted array that contains all the elements of the input matrix. 

Input: k = 4, n = 4, arr = { {1, 5, 6, 8}, {2, 4, 10, 12}, {3, 7, 9, 11}, {13, 14, 15, 16}} 
Output: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
Explanation: The output array is a sorted array that contains all the elements of the input matrix. 

Recommended Practice

Naive Approach for Merging k sorted arrays:

Create an output array of size (N * K) and then copy all the elements into the output array followed by sorting. 

Follow the given steps to solve the problem:

  • Create an output array of size N * K. 
  • Traverse the matrix from start to end and insert all the elements in the output array.
  • Sort and print the output array.

Below is the implementation of the above approach:

C++14




// C++ program to merge K sorted arrays of size n each.
  
#include <bits/stdc++.h>
using namespace std;
#define N 4
  
// A utility function to print array elements
void printArray(int arr[], int size)
{
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
}
  
// This function takes an array of arrays as an argument and
// All arrays are assumed to be sorted. It merges them
// together and prints the final sorted output.
void mergeKArrays(int arr[][N], int a, int output[])
{
    int c = 0;
  
    // traverse the matrix
    for (int i = 0; i < a; i++) {
        for (int j = 0; j < N; j++)
            output = arr[i][j];
    }
  
    // sort the array
    sort(output, output + N * a);
}
  
// Driver's code
int main()
{
    // Change N at the top to change number of elements
    // in an array
    int arr[][N] = { { 2, 6, 12, 34 },
                     { 1, 9, 20, 1000 },
                     { 23, 34, 90, 2000 } };
    int K = sizeof(arr) / sizeof(arr[0]);
  
    int output[N * K];
  
    // Function call
    mergeKArrays(arr, 3, output);
  
    cout << "Merged array is " << endl;
    printArray(output, N * K);
  
    return 0;
}


Java




// Java program to merge K sorted arrays of size N each.
  
import java.io.*;
import java.util.*;
  
class GFG {
  
    // This function takes an array of arrays as an argument
    // and
    // All arrays are assumed to be sorted. It merges them
    // together and prints the final sorted output.
    public static void mergeKArrays(int[][] arr, int a,
                                    int[] output)
    {
        int c = 0;
  
        // traverse the matrix
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < 4; j++)
                output = arr[i][j];
        }
  
        // sort the array
        Arrays.sort(output);
    }
  
    // A utility function to print array elements
    public static void printArray(int[] arr, int size)
    {
        for (int i = 0; i < size; i++)
            System.out.print(arr[i] + " ");
    }
  
    // Driver's code
    public static void main(String[] args)
    {
        int[][] arr = { { 2, 6, 12, 34 },
                        { 1, 9, 20, 1000 },
                        { 23, 34, 90, 2000 } };
        int K = 4;
        int N = 3;
        int[] output = new int[N * K];
  
        // Function call
        mergeKArrays(arr, N, output);
  
        System.out.println("Merged array is ");
        printArray(output, N * K);
    }
}


Python3




# Python3 program to merge k sorted arrays of size n each.
  
# This function takes an array of arrays as an argument
# and
# All arrays are assumed to be sorted. It merges them
# together and prints the final sorted output.
  
  
def mergeKArrays(arr, a, output):
    c = 0
  
    # traverse the matrix
    for i in range(a):
        for j in range(4):
            output = arr[i][j]
            c += 1
  
    # sort the array
    output.sort()
  
# A utility function to print array elements
  
  
def printArray(arr, size):
    for i in range(size):
        print(arr[i], end=" ")
  
  
# Driver's code
if __name__ == '__main__':
    arr = [[2, 6, 12, 34], [1, 9, 20, 1000], [23, 34, 90, 2000]]
    K = 4
    N = 3
    output = [0 for i in range(N * K)]
  
    # Function call
    mergeKArrays(arr, N, output)
  
    print("Merged array is ")
    printArray(output, N * K)
  
# This code is contributed by umadevi9616


C#




// C# program to merge K sorted arrays of size n each.
using System;
public class GFG {
  
    // This function takes an array of arrays as an argument
    // and
    // All arrays are assumed to be sorted. It merges them
    // together and prints the readonly sorted output.
    public static void mergeKArrays(int[, ] arr, int a,
                                    int[] output)
    {
        int c = 0;
  
        // traverse the matrix
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < 4; j++)
                output = arr[i, j];
        }
  
        // sort the array
        Array.Sort(output);
    }
  
    // A utility function to print array elements
    public static void printArray(int[] arr, int size)
    {
        for (int i = 0; i < size; i++)
            Console.Write(arr[i] + " ");
    }
  
    // Driver's code
    public static void Main(String[] args)
    {
        int[, ] arr = { { 2, 6, 12, 34 },
                        { 1, 9, 20, 1000 },
                        { 23, 34, 90, 2000 } };
        int K = 4;
        int N = 3;
        int[] output = new int[N * K];
  
        // Function call
        mergeKArrays(arr, N, output);
        Console.WriteLine("Merged array is ");
        printArray(output, N * K);
    }
}
  
// This code is contributed by Rajput-Ji


Javascript




// Javascript program to merge k sorted 
// arrays of size n each.
  
    // This function takes an array of 
    // arrays as an argument and
    // All arrays are assumed to be sorted. 
    // It merges them together and prints 
    // the final sorted output.
    function mergeKArrays(arr , a,  output)
    {
        var c = 0;
  
        // traverse the matrix
        for (i = 0; i < a; i++) {
            for (j = 0; j < 4; j++)
                output = arr[i][j];
        }
  
        // sort the array
        output.sort((a,b)=>a-b);
    }
  
    // A utility function to print array elements
    function printArray(arr , size) {
        for (i = 0; i < size; i++)
            document.write(arr[i] + " ");
    }
  
    // Driver program to test above functions
      
        var arr = [ [ 2, 6, 12, 34 ], 
                    [ 1, 9, 20, 1000 ], 
                    [ 23, 34, 90, 2000 ] ];
        var K = 4;
        var N = 3;
        var output = Array(N * K).fill(0);
  
        mergeKArrays(arr, N, output);
  
        document.write("Merged array is ");
        printArray(output, N * K);
  
  
// This code contributed by Rajput-Ji


Output

Merged array is 
1 2 6 9 12 20 23 34 34 90 1000 2000 

Time Complexity: O(N * K * log (N*K)), Since the resulting array is of size N*K.
Space Complexity: O(N * K), The output array is of size N * K.

Merge K sorted arrays using merging:

The process begins with merging arrays into groups of two. After the first merge, there will be K/2 arrays remaining. Again merge arrays in groups, now K/4 arrays will be remaining. This is similar to merge sort. Divide K arrays into two halves containing an equal number of arrays until there are two arrays in a group. This is followed by merging the arrays in a bottom-up manner. 

Follow the given steps to solve the problem:

  • Create a recursive function that takes K arrays and returns the output array.
  • In the recursive function, if the value of K is 1 then return the array else if the value of K is 2 then merge the two arrays in linear time and return the array.
  • If the value of K is greater than 2 then divide the group of k elements into two equal halves and recursively call the function, i.e 0 to K/2 array in one recursive function and K/2 to K array in another recursive function.
  • Print the output array.

Below is the implementation of the above approach:

C++14




// C++ program to merge K sorted arrays of size n each.
  
#include <bits/stdc++.h>
using namespace std;
#define N 4
  
// Merge arr1[0..N1-1] and arr2[0..N2-1] into
// arr3[0..N1+N2-1]
void mergeArrays(int arr1[], int arr2[], int N1, int N2,
                 int arr3[])
{
    int i = 0, j = 0, k = 0;
  
    // Traverse both array
    while (i < N1 && j < N2) {
        // Check if current element of first
        // array is smaller than current element
        // of second array. If yes, store first
        // array element and increment first array
        // index. Otherwise do same with second array
        if (arr1[i] < arr2[j])
            arr3[k++] = arr1[i++];
        else
            arr3[k++] = arr2[j++];
    }
  
    // Store remaining elements of first array
    while (i < N1)
        arr3[k++] = arr1[i++];
  
    // Store remaining elements of second array
    while (j < N2)
        arr3[k++] = arr2[j++];
}
  
// A utility function to print array elements
void printArray(int arr[], int size)
{
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
}
  
// This function takes an array of arrays as an argument and
// All arrays are assumed to be sorted. It merges them
// together and prints the final sorted output.
void mergeKArrays(int arr[][N], int i, int j, int output[])
{
    // If one array is in range
    if (i == j) {
        for (int p = 0; p < N; p++)
            output[p] = arr[i][p];
        return;
    }
  
    // if only two arrays are left them merge them
    if (j - i == 1) {
        mergeArrays(arr[i], arr[j], N, N, output);
        return;
    }
  
    // Output arrays
    int out1[N * (((i + j) / 2) - i + 1)],
        out2[N * (j - ((i + j) / 2))];
  
    // Divide the array into halves
    mergeKArrays(arr, i, (i + j) / 2, out1);
    mergeKArrays(arr, (i + j) / 2 + 1, j, out2);
  
    // Merge the output array
    mergeArrays(out1, out2, N * (((i + j) / 2) - i + 1),
                N * (j - ((i + j) / 2)), output);
}
  
// Driver's code
int main()
{
    // Change N at the top to change number of elements
    // in an array
    int arr[][N] = { { 2, 6, 12, 34 },
                     { 1, 9, 20, 1000 },
                     { 23, 34, 90, 2000 } };
    int K = sizeof(arr) / sizeof(arr[0]);
    int output[N * K];
    mergeKArrays(arr, 0, 2, output);
  
    // Function call
    cout << "Merged array is " << endl;
    printArray(output, N * K);
  
    return 0;
}


Java




// Java program to merge K sorted arrays of size n each.
import java.util.*;
  
class GFG {
    static final int N = 4;
  
    // Merge arr1[0..n1-1] and arr2[0..n2-1] into
    // arr3[0..n1+n2-1]
    static void mergeArrays(int arr1[], int arr2[], int N1,
                            int N2, int arr3[])
    {
        int i = 0, j = 0, k = 0;
  
        // Traverse both array
        while (i < N1 && j < N2) {
            // Check if current element of first
            // array is smaller than current element
            // of second array. If yes, store first
            // array element and increment first array
            // index. Otherwise do same with second array
            if (arr1[i] < arr2[j])
                arr3[k++] = arr1[i++];
            else
                arr3[k++] = arr2[j++];
        }
  
        // Store remaining elements of first array
        while (i < N1)
            arr3[k++] = arr1[i++];
  
        // Store remaining elements of second array
        while (j < N2)
            arr3[k++] = arr2[j++];
    }
  
    // A utility function to print array elements
    static void printArray(int arr[], int size)
    {
        for (int i = 0; i < size; i++)
            System.out.print(arr[i] + " ");
    }
  
    // This function takes an array of arrays as an argument
    // and All arrays are assumed to be sorted. It merges
    // them together and prints the final sorted output.
    static void mergeKArrays(int arr[][], int i, int j,
                             int output[])
    {
        // if one array is in range
        if (i == j) {
            for (int p = 0; p < N; p++)
                output[p] = arr[i][p];
            return;
        }
  
        // if only two arrays are left them merge them
        if (j - i == 1) {
            mergeArrays(arr[i], arr[j], N, N, output);
            return;
        }
  
        // output arrays
        int[] out1 = new int[N * (((i + j) / 2) - i + 1)];
        int[] out2 = new int[N * (j - ((i + j) / 2))];
  
        // divide the array into halves
        mergeKArrays(arr, i, (i + j) / 2, out1);
        mergeKArrays(arr, (i + j) / 2 + 1, j, out2);
  
        // merge the output array
        mergeArrays(out1, out2, N * (((i + j) / 2) - i + 1),
                    N * (j - ((i + j) / 2)), output);
    }
  
    // Driver's code
    public static void main(String[] args)
    {
  
        // Change n at the top to change number of elements
        // in an array
        int arr[][] = { { 2, 6, 12, 34 },
                        { 1, 9, 20, 1000 },
                        { 23, 34, 90, 2000 } };
  
        int K = arr.length;
        int[] output = new int[N * K];
  
        // Function call
        mergeKArrays(arr, 0, 2, output);
  
        System.out.print("Merged array is "
                         + "\n");
        printArray(output, N * K);
    }
}
  
// This code is contributed by gauravrajput1


Python3




# Python program to merge K
# sorted arrays of size n each.
N = 4
  
# Merge arr1[0..n1-1] and arr2[0..n2-1] into
# arr3[0..n1+n2-1]
  
  
def mergeArrays(arr1, arr2, N1, N2, arr3):
  
    i, j, k = 0, 0, 0
  
    # Traverse both array
    while (i < N1 and j < N2):
  
        # Check if current element of first
        # array is smaller than current element
        # of second array. If yes, store first
        # array element and increment first array
        # index. Otherwise do same with second array
        if (arr1[i] < arr2[j]):
            arr3[k] = arr1[i]
            k += 1
            i += 1
        else:
            arr3[k] = arr2[j]
            k += 1
            j += 1
  
    # Store remaining elements of first array
    while (i < N1):
        arr3[k] = arr1[i]
        k += 1
        i += 1
  
    # Store remaining elements of second array
    while (j < N2):
        arr3[k] = arr2[j]
        k += 1
        j += 1
  
# A utility function to print array elements
  
  
def printArray(arr, size):
  
    for i in range(size):
        print(arr[i], end=" ")
  
# This function takes an array of arrays
# as an argument and all arrays are assumed
# to be sorted. It merges them together
# and prints the final sorted output.
  
  
def mergeKArrays(arr, i, j, output):
  
    global N
  
    # If one array is in range
    if (i == j):
        for p in range(N):
            output[p] = arr[i][p]
  
        return
  
    # If only two arrays are left
    # them merge them
    if (j - i == 1):
        mergeArrays(arr[i], arr[j],
                    N, N, output)
        return
  
    # Output arrays
    out1 = [0 for i in range(N * (((i + j) // 2) - i + 1))]
    out2 = [0 for i in range(N * (j - ((i + j) // 2)))]
  
    # Divide the array into halves
    mergeKArrays(arr, i, (i + j) // 2, out1)
    mergeKArrays(arr, (i + j) // 2 + 1, j, out2)
  
    # Merge the output array
    mergeArrays(out1, out2,
                N * (((i + j) / 2) - i + 1),
                N * (j - ((i + j) / 2)), output)
  
  
# Driver's code
if __name__ == '__main__':
    arr = [[2, 6, 12, 34],
           [1, 9, 20, 1000],
           [23, 34, 90, 2000]]
  
    K = len(arr)
    output = [0 for i in range(N * K)]
  
    # Function call
    mergeKArrays(arr, 0, 2, output)
  
    print("Merged array is ")
    printArray(output, N * K)
  
# This code is contributed by shinjanpatra


C#




// C# program to merge K sorted arrays of size n each.
using System;
  
class GFG {
  
    static readonly int N = 4;
  
    public static int[] GetRow(int[, ] matrix, int row)
    {
        var rowLength = matrix.GetLength(1);
        var rowVector = new int[rowLength];
  
        for (var i = 0; i < rowLength; i++)
            rowVector[i] = matrix[row, i];
  
        return rowVector;
    }
  
    // Merge arr1[0..n1-1] and arr2[0..n2-1] into
    // arr3[0..n1+n2-1]
    static void mergeArrays(int[] arr1, int[] arr2, int N1,
                            int N2, int[] arr3)
    {
        int i = 0, j = 0, k = 0;
  
        // Traverse both array
        while (i < N1 && j < N2) {
  
            // Check if current element of first
            // array is smaller than current element
            // of second array. If yes, store first
            // array element and increment first array
            // index. Otherwise do same with second array
            if (arr1[i] < arr2[j])
                arr3[k++] = arr1[i++];
            else
                arr3[k++] = arr2[j++];
        }
  
        // Store remaining elements of first array
        while (i < N1)
            arr3[k++] = arr1[i++];
  
        // Store remaining elements of second array
        while (j < N2)
            arr3[k++] = arr2[j++];
    }
  
    // A utility function to print array elements
    static void printArray(int[] arr, int size)
    {
        for (int i = 0; i < size; i++)
            Console.Write(arr[i] + " ");
    }
  
    // This function takes an array of arrays as an
    // argument and All arrays are assumed to be
    // sorted. It merges them together and prints
    // the readonly sorted output.
    static void mergeKArrays(int[, ] arr, int i, int j,
                             int[] output)
    {
  
        // If one array is in range
        if (i == j) {
            for (int p = 0; p < N; p++)
                output[p] = arr[i, p];
  
            return;
        }
  
        // If only two arrays are left them merge them
        if (j - i == 1) {
            mergeArrays(GetRow(arr, i), GetRow(arr, j), N,
                        N, output);
            return;
        }
  
        // Output arrays
        int[] out1 = new int[N * (((i + j) / 2) - i + 1)];
        int[] out2 = new int[N * (j - ((i + j) / 2))];
  
        // Divide the array into halves
        mergeKArrays(arr, i, (i + j) / 2, out1);
        mergeKArrays(arr, (i + j) / 2 + 1, j, out2);
  
        // Merge the output array
        mergeArrays(out1, out2, N * (((i + j) / 2) - i + 1),
                    N * (j - ((i + j) / 2)), output);
    }
  
    // Driver's code
    public static void Main(String[] args)
    {
  
        // Change n at the top to change number of elements
        // in an array
        int[, ] arr = { { 2, 6, 12, 34 },
                        { 1, 9, 20, 1000 },
                        { 23, 34, 90, 2000 } };
        int K = arr.GetLength(0);
        int[] output = new int[N * K];
  
        // Function call
        mergeKArrays(arr, 0, 2, output);
  
        Console.Write("Merged array is "
                      + "\n");
        printArray(output, N * K);
    }
}
  
// This code is contributed by Rajput-Ji


Javascript




// Javascript program to merge k 
// sorted arrays of size n each.
let N =  4
  
// Merge arr1[0..n1-1] and arr2[0..n2-1] into
// arr3[0..n1+n2-1]
function mergeArrays(arr1, arr2, N1, N2, arr3)
{
    let i = 0, j = 0, k = 0;
  
    // Traverse both array
    while (i < N1 && j < N2)
    {
          
        // Check if current element of first
        // array is smaller than current element
        // of second array. If yes, store first
        // array element and increment first array
        // index. Otherwise do same with second array
        if (arr1[i] < arr2[j])
            arr3[k++] = arr1[i++];
        else
            arr3[k++] = arr2[j++];
    }
      
    // Store remaining elements of first array
    while (i < N1)
        arr3[k++] = arr1[i++];
  
    // Store remaining elements of second array
    while (j < N2)
        arr3[k++] = arr2[j++];
}
  
// A utility function to print array elements
function printArray(arr, size)
{
    for(let i = 0; i < size; i++)
        document.write(arr[i] + " ");
}
  
// This function takes an array of arrays 
// as an argument and all arrays are assumed 
// to be sorted. It merges them together
// and prints the final sorted output.
function mergeKArrays(arr, i, j, output)
{
      
    // If one array is in range
    if (i == j)
    {
        for(let p = 0; p < N; p++)
            output[p] = arr[i][p];
              
        return;
    }
      
    // If only two arrays are left 
    // them merge them
    if (j - i == 1)
    {
        mergeArrays(arr[i], arr[j],
                    N, N, output);
        return;
    }
      
    // Output arrays
    let out1 = new Array(N * (((i + j) / 2) - i + 1))
    let out2 = new Array(N * (j - ((i + j) / 2)));
      
    // Divide the array into halves
    mergeKArrays(arr, i, (i + j) / 2, out1);
    mergeKArrays(arr, (i + j) / 2 + 1, j, out2);
      
    // Merge the output array
    mergeArrays(out1, out2, 
                N * (((i + j) / 2) - i + 1),
                N * (j - ((i + j) / 2)), output);
}
  
// Driver code
  
// Change n at the top to change number
// of elements in an array
let arr = [ [ 2, 6, 12, 34 ],
            [ 1, 9, 20, 1000 ],
            [ 23, 34, 90, 2000 ] ];
let K = arr.length;
let output = new Array(N * K);
  
mergeKArrays(arr, 0, 2, output);
  
document.write("Merged array is " + "<br>");
printArray(output, N * K);
  
// This code is contributed by Mayank Tyagi


Output

Merged array is 
1 2 6 9 12 20 23 34 34 90 1000 2000 

Time Complexity: O(N * K * log K).  There are log K levels as in each level the K arrays are divided in half and at each level, the K arrays are traversed.
Auxiliary Space: O(N * K * log K). In each level O(N * K) space is required.

Merge K sorted arrays using Min-Heap:

The idea is to use Min Heap. This MinHeap based solution has the same time complexity which is O(NK log K). But for a different and particular sized array, this solution works much better. The process must start with creating a MinHeap and inserting the first element of all the k arrays. Remove the root element of Minheap and put it in the output array and insert the next element from the array of removed element. To get the result the step must continue until there is no element left in the MinHeap. 

Follow the given steps to solve the problem:

  • Create a min Heap and insert the first element of all the K arrays.
  • Run a loop until the size of MinHeap is greater than zero.
    • Remove the top element of the MinHeap and print the element.
    • Now insert the next element from the same array in which the removed element belonged.
    • If the array doesn’t have any more elements, then replace root with infinite. After replacing the root, heapify the tree.
  • Return the output array

Below is the implementation of the above approach:

C++




// C++ program to merge K sorted
// arrays of size N each.
#include <bits/stdc++.h>
using namespace std;
  
#define N 4
  
// A min-heap node
struct MinHeapNode {
    // The element to be stored
    int element;
  
    // index of the array from which the element is taken
    int i;
  
    // index of the next element to be picked from the array
    int j;
};
  
// Prototype of a utility function to swap two min-heap
// nodes
void swap(MinHeapNode* x, MinHeapNode* y);
  
// A class for Min Heap
class MinHeap {
  
    // pointer to array of elements in heap
    MinHeapNode* harr;
  
    // size of min heap
    int heap_size;
  
public:
    // Constructor: creates a min heap of given size
    MinHeap(MinHeapNode a[], int size);
  
    // to heapify a subtree with root at given index
    void MinHeapify(int);
  
    // to get index of left child of node at index i
    int left(int i) { return (2 * i + 1); }
  
    // to get index of right child of node at index i
    int right(int i) { return (2 * i + 2); }
  
    // to get the root
    MinHeapNode getMin() { return harr[0]; }
  
    // to replace root with new node x and heapify() new
    // root
    void replaceMin(MinHeapNode x)
    {
        harr[0] = x;
        MinHeapify(0);
    }
};
  
// This function takes an array of arrays as an argument and
// All arrays are assumed to be sorted. It merges them
// together and prints the final sorted output.
int* mergeKArrays(int arr[][N], int K)
{
  
    // To store output array
    int* output = new int[N * K];
  
    // Create a min heap with k heap nodes.
    // Every heap node has first element of an array
    MinHeapNode* harr = new MinHeapNode[K];
    for (int i = 0; i < K; i++) {
  
        // Store the first element
        harr[i].element = arr[i][0];
  
        // index of array
        harr[i].i = i;
  
        // Index of next element to be stored from the array
        harr[i].j = 1;
    }
  
    // Create the heap
    MinHeap hp(harr, K);
  
    // Now one by one get the minimum element from min
    // heap and replace it with next element of its array
    for (int count = 0; count < N * K; count++) {
        // Get the minimum element and store it in output
        MinHeapNode root = hp.getMin();
        output[count] = root.element;
  
        // Find the next element that will replace current
        // root of heap. The next element belongs to same
        // array as the current root.
        if (root.j < N) {
            root.element = arr[root.i][root.j];
            root.j += 1;
        }
        // If root was the last element of its array
        // INT_MAX is for infinite
        else
            root.element = INT_MAX;
  
        // Replace root with next element of array
        hp.replaceMin(root);
    }
  
    return output;
}
  
// FOLLOWING ARE IMPLEMENTATIONS OF
// STANDARD MIN HEAP METHODS FROM CORMEN BOOK
// Constructor: Builds a heap from a given
// array a[] of given size
MinHeap::MinHeap(MinHeapNode a[], int size)
{
    heap_size = size;
    harr = a; // store address of array
    int i = (heap_size - 1) / 2;
    while (i >= 0) {
        MinHeapify(i);
        i--;
    }
}
  
// A recursive method to heapify a
// subtree with root at given index.
// This method assumes that the subtrees
// are already heapified
void MinHeap::MinHeapify(int i)
{
    int l = left(i);
    int r = right(i);
    int smallest = i;
  
    if (l < heap_size && harr[l].element < harr[i].element)
        smallest = l;
  
    if (r < heap_size
        && harr[r].element < harr[smallest].element)
        smallest = r;
  
    if (smallest != i) {
        swap(&harr[i], &harr[smallest]);
        MinHeapify(smallest);
    }
}
  
// A utility function to swap two elements
void swap(MinHeapNode* x, MinHeapNode* y)
{
    MinHeapNode temp = *x;
    *x = *y;
    *y = temp;
}
  
// A utility function to print array elements
void printArray(int arr[], int size)
{
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
}
  
// Driver's code
int main()
{
    // Change N at the top to change number of elements
    // in an array
    int arr[][N] = { { 2, 6, 12, 34 },
                     { 1, 9, 20, 1000 },
                     { 23, 34, 90, 2000 } };
    int K = sizeof(arr) / sizeof(arr[0]);
  
    // Function call
    int* output = mergeKArrays(arr, K);
  
    cout << "Merged array is " << endl;
    printArray(output, N * K);
  
    return 0;
}


Java




// Java program to merge K sorted
// arrays of size N each.
  
// A Min heap node
class MinHeapNode {
    int element; // The element to be stored
  
    // index of the array from
    // which the element is taken
    int i;
  
    // index of the next element
    // to be picked from array
    int j;
  
    public MinHeapNode(int element, int i, int j)
    {
        this.element = element;
        this.i = i;
        this.j = j;
    }
};
  
// A class for Min Heap
class MinHeap {
    MinHeapNode[] harr; // Array of elements in heap
    int heap_size; // Current number of elements in min heap
  
    // Constructor: Builds a heap from
    // a given array a[] of given size
    public MinHeap(MinHeapNode a[], int size)
    {
        heap_size = size;
        harr = a;
        int i = (heap_size - 1) / 2;
        while (i >= 0) {
            MinHeapify(i);
            i--;
        }
    }
  
    // A recursive method to heapify a subtree
    // with the root at given index This method
    // assumes that the subtrees are already heapified
    void MinHeapify(int i)
    {
        int l = left(i);
        int r = right(i);
        int smallest = i;
  
        if (l < heap_size
            && harr[l].element < harr[i].element)
            smallest = l;
  
        if (r < heap_size
            && harr[r].element < harr[smallest].element)
            smallest = r;
  
        if (smallest != i) {
            swap(harr, i, smallest);
            MinHeapify(smallest);
        }
    }
  
    // to get index of left child of node at index i
    int left(int i) { return (2 * i + 1); }
  
    // to get index of right child of node at index i
    int right(int i) { return (2 * i + 2); }
  
    // to get the root
    MinHeapNode getMin()
    {
        if (heap_size <= 0) {
            System.out.println("Heap underflow");
            return null;
        }
        return harr[0];
    }
  
    // to replace root with new node
    // "root" and heapify() new root
    void replaceMin(MinHeapNode root)
    {
        harr[0] = root;
        MinHeapify(0);
    }
  
    // A utility function to swap two min heap nodes
    void swap(MinHeapNode[] arr, int i, int j)
    {
        MinHeapNode temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
  
    // A utility function to print array elements
    static void printArray(int[] arr)
    {
        for (int i : arr)
            System.out.print(i + " ");
        System.out.println();
    }
  
    // This function takes an array of
    // arrays as an argument and All
    // arrays are assumed to be sorted.
    // It merges them together and
    // prints the final sorted output.
    static void mergeKSortedArrays(int[][] arr, int K)
    {
        MinHeapNode[] hArr = new MinHeapNode[K];
        int resultSize = 0;
        for (int i = 0; i < arr.length; i++) {
            MinHeapNode node
                = new MinHeapNode(arr[i][0], i, 1);
            hArr[i] = node;
            resultSize += arr[i].length;
        }
  
        // Create a min heap with k heap nodes. Every heap
        // node has first element of an array
        MinHeap mh = new MinHeap(hArr, K);
  
        int[] result
            = new int[resultSize]; // To store output array
  
        // Now one by one get the minimum element from min
        // heap and replace it with next element of its
        // array
        for (int i = 0; i < resultSize; i++) {
  
            // Get the minimum element and store it in
            // result
            MinHeapNode root = mh.getMin();
            result[i] = root.element;
  
            // Find the next element that will replace
            // current root of heap. The next element
            // belongs to same array as the current root.
            if (root.j < arr[root.i].length)
                root.element = arr[root.i][root.j++];
            // If root was the last element of its array
            else
                root.element = Integer.MAX_VALUE;
  
            // Replace root with next element of array
            mh.replaceMin(root);
        }
  
        printArray(result);
    }
  
    // Driver's code
    public static void main(String args[])
    {
        int[][] arr = { { 2, 6, 12, 34 },
                        { 1, 9, 20, 1000 },
                        { 23, 34, 90, 2000 } };
  
        System.out.println("Merged array is :");
  
        // Function call
        mergeKSortedArrays(arr, arr.length);
    }
};
  
// This code is contributed by shubham96301


Python3




import sys
  
# Python 3 program to merge K sorted
# arrays of size N each.
# A Min heap node
class MinHeapNode :
    element = 0
      
    # The element to be stored
    # index of the array from
    # which the element is taken
    i = 0
      
    # index of the next element
    # to be picked from array
    j = 0
    def __init__(self, element,  i,  j) :
        self.element = element
        self.i = i
        self.j = j
          
# A class for Min Heap
class MinHeap :
    harr = None
      
    # Array of elements in heap
    heap_size = 0
      
    # Current number of elements in min heap
    # Constructor: Builds a heap from
    # a given array a[] of given size
    def __init__(self, a,  size) :
        self.heap_size = size
        self.harr = a
        i = int((self.heap_size - 1) / 2)
        while (i >= 0) :
            self.MinHeapify(i)
            i -= 1
              
    # A recursive method to heapify a subtree
    # with the root at given index This method
    # assumes that the subtrees are already heapified
    def MinHeapify(self, i) :
        l = self.left(i)
        r = self.right(i)
        smallest = i
        if (l < self.heap_size and self.harr[l].element < self.harr[i].element) :
            smallest = l
        if (r < self.heap_size and self.harr[r].element < self.harr[smallest].element) :
            smallest = r
        if (smallest != i) :
            self.swap(self.harr, i, smallest)
            self.MinHeapify(smallest)
              
    # to get index of left child of node at index i
    def  left(self, i) :
        return (2 * i + 1)
        
    # to get index of right child of node at index i
    def  right(self, i) :
        return (2 * i + 2)
        
    # to get the root
    def  getMin(self) :
        if (self.heap_size <= 0) :
            print("Heap underflow")
            return None
        return self.harr[0]
        
    # to replace root with new node
    # "root" and heapify() new root
    def replaceMin(self, root) :
        self.harr[0] = root
        self.MinHeapify(0)
          
    # A utility function to swap two min heap nodes
    def swap(self, arr,  i,  j) :
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
          
    # A utility function to print array elements
    @staticmethod
    def printArray( arr) :
        for i in arr :
            print(str(i) + " ", end ="")
        print()
          
    # This function takes an array of
    # arrays as an argument and All
    # arrays are assumed to be sorted.
    # It merges them together and
    # prints the final sorted output.
    @staticmethod
    def mergeKSortedArrays( arr,  K) :
        hArr = [None] * (K)
        resultSize = 0
        i = 0
        while (i < len(arr)) :
            node = MinHeapNode(arr[i][0], i, 1)
            hArr[i] = node
            resultSize += len(arr[i])
            i += 1
              
        # Create a min heap with k heap nodes. Every heap
        # node has first element of an array
        mh = MinHeap(hArr, K)
        result = [0] * (resultSize)
          
        # To store output array
        # Now one by one get the minimum element from min
        # heap and replace it with next element of its
        # array
        i = 0
        while (i < resultSize) :
            
            # Get the minimum element and store it in
            # result
            root = mh.getMin()
            result[i] = root.element
              
            # Find the next element that will replace
            # current root of heap. The next element
            # belongs to same array as the current root.
            if (root.j < len(arr[root.i])) :
                root.element = arr[root.i][root.j]
                root.j += 1
            else :
                root.element = sys.maxsize
                  
            # Replace root with next element of array
            mh.replaceMin(root)
            i += 1
        MinHeap.printArray(result)
          
    # Driver's code
    @staticmethod
    def main( args) :
        arr = [[2, 6, 12, 34], [1, 9, 20, 1000], [23, 34, 90, 2000]]
        print("Merged array is :")
        # Function call
        MinHeap.mergeKSortedArrays(arr, len(arr))
      
if __name__=="__main__":
    MinHeap.main([])
      
    # This code is contributed by aadityaburujwale.


C#




// C# program to merge K sorted
// arrays of size N each.
  
using System;
  
// A Min heap node
public class MinHeapNode {
    public int element; // The element to be stored
  
    // index of the array from
    // which the element is taken
    public int i;
  
    // index of the next element
    // to be picked from array
    public int j;
  
    public MinHeapNode(int element, int i, int j)
    {
        this.element = element;
        this.i = i;
        this.j = j;
    }
};
  
// A class for Min Heap
public class MinHeap {
    MinHeapNode[] harr; // Array of elements in heap
    int heap_size; // Current number of elements in min heap
  
    // Constructor: Builds a heap from
    // a given array a[] of given size
    public MinHeap(MinHeapNode[] a, int size)
    {
        heap_size = size;
        harr = a;
        int i = (heap_size - 1) / 2;
        while (i >= 0) {
            MinHeapify(i);
            i--;
        }
    }
  
    // A recursive method to heapify a subtree
    // with the root at given index This method
    // assumes that the subtrees are already heapified
    void MinHeapify(int i)
    {
        int l = left(i);
        int r = right(i);
        int smallest = i;
  
        if (l < heap_size
            && harr[l].element < harr[i].element)
            smallest = l;
  
        if (r < heap_size
            && harr[r].element < harr[smallest].element)
            smallest = r;
  
        if (smallest != i) {
            swap(harr, i, smallest);
            MinHeapify(smallest);
        }
    }
  
    // to get index of left child of node at index i
    int left(int i) { return (2 * i + 1); }
  
    // to get index of right child of node at index i
    int right(int i) { return (2 * i + 2); }
  
    // to get the root
    MinHeapNode getMin()
    {
        if (heap_size <= 0) {
            Console.WriteLine("Heap underflow");
            return null;
        }
        return harr[0];
    }
  
    // to replace root with new node
    // "root" and heapify() new root
    void replaceMin(MinHeapNode root)
    {
        harr[0] = root;
        MinHeapify(0);
    }
  
    // A utility function to swap two min heap nodes
    void swap(MinHeapNode[] arr, int i, int j)
    {
        MinHeapNode temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
  
    // A utility function to print array elements
    static void printArray(int[] arr)
    {
        foreach(int i in arr) Console.Write(i + " ");
        Console.WriteLine();
    }
  
    // This function takes an array of
    // arrays as an argument and All
    // arrays are assumed to be sorted.
    // It merges them together and
    // prints the final sorted output.
    static void mergeKSortedArrays(int[, ] arr, int K)
    {
        MinHeapNode[] hArr = new MinHeapNode[K];
        int resultSize = 0;
        for (int i = 0; i < arr.GetLength(0); i++) {
            MinHeapNode node
                = new MinHeapNode(arr[i, 0], i, 1);
            hArr[i] = node;
            resultSize += arr.GetLength(1);
        }
  
        // Create a min heap with k heap nodes.
        // Every heap node has first element of an array
        MinHeap mh = new MinHeap(hArr, K);
  
        int[] result
            = new int[resultSize]; // To store output array
  
        // Now one by one get the minimum element
        // from min heap and replace it with
        // next element of its array
        for (int i = 0; i < resultSize; i++) {
  
            // Get the minimum element and
            // store it in result
            MinHeapNode root = mh.getMin();
            result[i] = root.element;
  
            // Find the next element that will
            // replace current root of heap.
            // The next element belongs to same
            // array as the current root.
            if (root.j < arr.GetLength(1))
                root.element = arr[root.i, root.j++];
  
            // If root was the last element of its array
            else
                root.element = int.MaxValue;
  
            // Replace root with next element of array
            mh.replaceMin(root);
        }
        printArray(result);
    }
  
    // Driver's code
    public static void Main(String[] args)
    {
        int[, ] arr = { { 2, 6, 12, 34 },
                        { 1, 9, 20, 1000 },
                        { 23, 34, 90, 2000 } };
  
        Console.WriteLine("Merged array is :");
  
        // Function call
        mergeKSortedArrays(arr, arr.GetLength(0));
    }
};
  
// This code is contributed by 29AjayKumar


Javascript




function countPaths(n, m, k, a) {
  // cnt1: number of steps in left part
  // cnt2: number of steps in right part
  let cnt1 = Math.floor((n + m - 2) / 2);
  let cnt2 = (n + m - 2) - cnt1;
    
  // Edge case: matrix is 1x1 and the only element is k
  if (n === 1 && m === 1 && a[0][0] === k) {
    return 1;
  }
  
  const mp1 = {}; // left part
  const mp2 = {}; // right part
  
  // Recursive function for left part
  function part1(i, j, cnt, zor) {
    if (cnt <= 0) {
      // Count the number of triplets
      if (!mp1[zor]) {
        mp1[zor] = {};
      }
      if (!mp1[zor][i]) {
        mp1[zor][i] = {};
      }
      if (!mp1[zor][i][j]) {
        mp1[zor][i][j] = 0;
      }
      mp1[zor][i][j]++;
      return;
    }
      
    // Move rightwards
    if (j + 1 < m) {
      part1(i, j + 1, cnt - 1, zor ^ a[i][j + 1]);
    }
      
    // Move downwards
    if (i + 1 < n) {
      part1(i + 1, j, cnt - 1, zor ^ a[i + 1][j]);
    }
  }
  
  // Recursive function for right part
  function part2(i, j, cnt, zor) {
    if (cnt <= 0) {
      // Count the number of triplets
      if (!mp2[zor]) {
        mp2[zor] = {};
      }
      if (!mp2[zor][i]) {
        mp2[zor][i] = {};
      }
      if (!mp2[zor][i][j]) {
        mp2[zor][i][j] = 0;
      }
      mp2[zor][i][j]++;
      return;
    }
      
    // Move leftwards
    if (j - 1 >= 0) {
      part2(i, j - 1, cnt - 1, zor ^ a[i][j - 1]);
    }
      
    // Move upwards
    if (i - 1 >= 0) {
      part2(i - 1, j, cnt - 1, zor ^ a[i - 1][j]);
    }
  }
  
  // Call the recursive functions for left and right parts
  part1(0, 0, cnt1, a[0][0]);
  part2(n - 1, m - 1, cnt2 - 1, a[n - 1][m - 1]);
  
  let ans = 0;
  // Iterate through the triplets in the right part
  for (const zor in mp2) {
    for (const i in mp


Output

Merged array is 
1 2 6 9 12 20 23 34 34 90 1000 2000 

Time Complexity: O(N * K * log K), Insertion and deletion in a Min Heap requires log K time.
Auxiliary Space: O(K), If Output is not stored then the only space required is the Min-Heap of K elements.

Merge k sorted arrays | Set 2 (Different Sized Arrays)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments