Open In App

Merge K sorted arrays of different sizes | ( Divide and Conquer Approach )

Given k sorted arrays of different length, merge them into a single array such that the merged array is also sorted.
Examples: 

Input : {{3, 13}, 
        {8, 10, 11}
        {9, 15}}
Output : {3, 8, 9, 10, 11, 13, 15}

Input : {{1, 5}, 
         {2, 3, 4}}
Output : {1, 2, 3, 4, 5}
 

Let S be the total number of elements in all the arrays.
Simple Approach: A simple approach is to append the arrays one after another and sort them. Time complexity in this case will be O( S * log(S)).
Efficient Approach: An efficient solution will be to take pairs of arrays at each step. Then merge the pairs using the two pointer technique of merging two sorted arrays. Thus, after merging all the pairs, the number of arrays will reduce by half. 
We, will continue this till the number of remaining arrays doesn’t become 1. Thus, the number of steps required will be of the order log(k) and since at each step, we are taking O(S) time to perform the merge operations, the total time complexity of this approach becomes O(S * log(k)).
We already have discussed this approach for merging K sorted arrays of same sizes.
Since in this problem the arrays are of different sizes, we will use dynamic arrays ( eg: vector in case of C++ or arraylist in case of Java ) because they reduce the number of lines and work load significantly.
Below is the implementation of the above approach:
 






// C++ program to merge K sorted arrays of
// different arrays
 
#include <iostream>
#include <vector>
using namespace std;
 
// Function to merge two arrays
vector<int> mergeTwoArrays(vector<int> l, vector<int> r)
{
    // array to store the result
    // after merging l and r
    vector<int> ret;
 
    // variables to store the current
    // pointers for l and r
    int l_in = 0, r_in = 0;
 
    // loop to merge l and r using two pointer
    while (l_in + r_in < l.size() + r.size()) {
        if (l_in != l.size() && (r_in == r.size() || l[l_in] < r[r_in])) {
            ret.push_back(l[l_in]);
            l_in++;
        }
        else {
            ret.push_back(r[r_in]);
            r_in++;
        }
    }
 
    return ret;
}
 
// Function to merge all the arrays
vector<int> mergeArrays(vector<vector<int> > arr)
{
    // 2D-array to store the results of
    // a step temporarily
    vector<vector<int> > arr_s;
 
    // Loop to make pairs of arrays and merge them
    while (arr.size() != 1) {
 
        // To clear the data of previous steps
        arr_s.clear();
 
        for (int i = 0; i < arr.size(); i += 2) {
            if (i == arr.size() - 1)
                arr_s.push_back(arr[i]);
 
            else
                arr_s.push_back(mergeTwoArrays(arr[i],
                                               arr[i + 1]));
        }
 
        arr = arr_s;
    }
 
    // Returning the required output array
    return arr[0];
}
 
// Driver Code
int main()
{
    // Input arrays
    vector<vector<int> > arr{ { 3, 13 },
                              { 8, 10, 11 },
                              { 9, 15 } };
    // Merged sorted array
    vector<int> output = mergeArrays(arr);
 
    for (int i = 0; i < output.size(); i++)
        cout << output[i] << " ";
 
    return 0;
}




/*
Java program to merge k sorted arrays of different sizes
*/
 
import java.io.*;
import java.util.ArrayList;
import java.util.List;
 
 
class GFG {
    // Function to merge two arrays
    public static List<Integer> mergeTwoArrays(List<Integer> l, List<Integer> r) {
        // list to store the result
        // after merging l and r
        List<Integer> ret = new ArrayList<>();
 
        // variables to store the current
        // pointers for l and r
        int lIn = 0, rIn = 0;
 
        // loop to merge l and r using two pointer
        while (lIn + rIn < l.size() + r.size()) {
            if (lIn != l.size() && (rIn == r.size() || l.get(lIn) < r.get(rIn))) {
                ret.add(l.get(lIn));
                lIn += 1;
            } else {
                ret.add(r.get(rIn));
                rIn += 1;
            }
        }
 
        return ret;
    }
 
    // Function to merge all the arrays
    public static List<Integer> mergeArrays(List<List<Integer>> arr) {
         
 
        // Loop to make pairs of arrays
        // and merge them
        while (arr.size() != 1) {
           
            // 2D-array to store the results
            // of a step temporarily
            List<List<Integer>> arrS = new ArrayList<>();
 
            for (int i = 0; i < arr.size(); i += 2) {
                if (i == arr.size() - 1) {
                    arrS.add(arr.get(i));
                } else {
                    arrS.add(mergeTwoArrays(arr.get(i), arr.get(i + 1)));
                }
            }
 
            arr = arrS;
        }
 
        // Returning the required output array
        return arr.get(0);
    }
 
    public static void main(String[] args) {
        // Input arrays
        List<List<Integer>> arr = new ArrayList<>();
        arr.add(List.of(3, 13));
        arr.add(List.of(8, 10, 11));
        arr.add(List.of(9, 15));
 
        // Merged sorted array
        List<Integer> output = mergeArrays(arr);
 
        for (int i = 0; i < output.size(); i++) {
            System.out.print(output.get(i) + " ");
        }
    }
}
 
// This code is contributed by Harshad




# Python3 program to merge K sorted
# arrays of different arrays
 
# Function to merge two arrays
def mergeTwoArrays(l, r):
 
    # array to store the result
    # after merging l and r
    ret = []
 
    # variables to store the current
    # pointers for l and r
    l_in, r_in = 0, 0
 
    # loop to merge l and r using two pointer
    while l_in + r_in < len(l) + len(r):
        if (l_in != len(l) and
           (r_in == len(r) or
            l[l_in] < r[r_in])):
                 
            ret.append(l[l_in])
            l_in += 1
         
        else:
            ret.append(r[r_in])
            r_in += 1
 
    return ret
 
# Function to merge all the arrays
def mergeArrays(arr):
 
    # 2D-array to store the results
    # of a step temporarily
    arr_s = []
 
    # Loop to make pairs of arrays
    # and merge them
    while len(arr) != 1:
 
        # To clear the data of previous steps
        arr_s[:] = []
 
        for i in range(0, len(arr), 2):
            if i == len(arr) - 1:
                arr_s.append(arr[i])
 
            else:
                arr_s.append(mergeTwoArrays(arr[i],
                                            arr[i + 1]))
 
        arr = arr_s[:]
 
    # Returning the required output array
    return arr[0]
 
# Driver Code
if __name__ == "__main__":
 
    # Input arrays
    arr = [[3, 13],
        [8, 10, 11],
        [9, 15]]
             
    # Merged sorted array
    output = mergeArrays(arr)
 
    for i in range(0, len(output)):
        print(output[i], end = " ")
 
# This code is contributed by Rituraj Jain




using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Function to merge two arrays
  static List<int> mergeTwoArrays(List<int> l, List<int> r) {
 
    // array to store the result
    // after merging l and r
    List<int> ret = new List<int>();
 
    // variables to store the current
    // pointers for l and r
    int l_in = 0, r_in = 0;
 
    // loop to merge l and r using two pointer
    while (l_in + r_in < l.Count + r.Count) {
      if (l_in != l.Count &&
          (r_in == r.Count || l[l_in] < r[r_in])) {
 
        ret.Add(l[l_in]);
        l_in += 1;
 
      } else {
        ret.Add(r[r_in]);
        r_in += 1;
      }
    }
 
    return ret;
  }
 
  // Function to merge all the arrays
  static List<int> mergeArrays(List<List<int>> arr) {
 
    // 2D-array to store the results
    // of a step temporarily
    List<List<int>> arr_s = new List<List<int>>();
 
    // Loop to make pairs of arrays
    // and merge them
    while (arr.Count != 1) {
 
      // To clear the data of previous steps
      arr_s.Clear();
 
      for (int i = 0; i < arr.Count; i += 2) {
        if (i == arr.Count - 1) {
          arr_s.Add(arr[i]);
        } else {
          arr_s.Add(mergeTwoArrays(arr[i], arr[i + 1]));
        }
      }
 
      arr = arr_s.GetRange(0, arr_s.Count);
    }
 
    // Returning the required output array
    return arr[0];
  }
 
  // Driver Code
  public static void Main() {
 
    // Input arrays
    List<List<int>> arr = new List<List<int>> {
      new List<int> {3, 13},
      new List<int> {8, 10, 11},
      new List<int> {9, 15}
    };
 
    // Merged sorted array
    List<int> output = mergeArrays(arr);
 
    for (int i = 0; i < output.Count; i++) {
      Console.Write(output[i] + " ");
    }
  }
}




<script>
 
// Javascript program to merge K sorted arrays of
// different arrays
 
// Function to merge two arrays
function mergeTwoArrays(l, r)
{
 
    // array to store the result
    // after merging l and r
    var ret = [];
 
    // variables to store the current
    // pointers for l and r
    var l_in = 0, r_in = 0;
 
    // loop to merge l and r using two pointer
    while (l_in + r_in < l.length + r.length) {
        if (l_in != l.length && (r_in == r.length || l[l_in] < r[r_in])) {
            ret.push(l[l_in]);
            l_in++;
        }
        else {
            ret.push(r[r_in]);
            r_in++;
        }
    }
 
    return ret;
}
 
// Function to merge all the arrays
function mergeArrays(arr)
{
    // 2D-array to store the results of
    // a step temporarily
    var arr_s = [];
 
    // Loop to make pairs of arrays and merge them
    while (arr.length != 1) {
 
        // To clear the data of previous steps
        arr_s = [];
 
        for (var i = 0; i < arr.length; i += 2) {
            if (i == arr.length - 1)
                arr_s.push(arr[i]);
 
            else
                arr_s.push(mergeTwoArrays(arr[i],
                                               arr[i + 1]));
        }
 
        arr = arr_s;
    }
 
    // Returning the required output array
    return arr[0];
}
 
// Driver Code
// Input arrays
var arr = [ [ 3, 13 ],
                          [ 8, 10, 11 ],
                          [ 9, 15 ] ];
// Merged sorted array
var output = mergeArrays(arr);
for (var i = 0; i < output.length; i++)
    document.write(output[i] + " ");
 
// This code is contributed by rrrtnx.
</script>

Output
3 8 9 10 11 13 15 

Time Complexity: O(S*logK)
Auxiliary Space: O(logK)
Note that there exist a better solution using heap (or priority queue). The time complexity of the heap based solution is O(N Log k) where N is the total number of elements in all K arrays. 
 




Article Tags :