📜  合并 K 个不同大小的排序数组 | (分而治之的方法)

📅  最后修改于: 2021-09-16 11:18:49             🧑  作者: Mango

给定k 个不同长度的已排序数组,将它们合并为一个数组,这样合并后的数组也已排序。

例子:

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}

令 S 为所有数组中元素的总数。

简单的方法:一种简单的方法是将数组一个接一个地附加并排序。在这种情况下,时间复杂度为O( S * log(S))

有效的方法:一个有效的解决方案是在每一步都采用成对的数组。然后使用合并两个已排序数组的双指针技术合并这些对。因此,合并所有对后,数组的数量将减少一半。

我们将继续这样做,直到剩余数组的数量不会变成 1。因此,所需的步骤数将是 log(k) 的顺序,因为在每一步,我们都需要 O(S) 时间来执行合并操作,这种方法的总时间复杂度变为O(S * log(k))

我们已经讨论过这种合并 K 个相同大小的排序数组的方法。

由于在这个问题中数组的大小不同,我们将使用动态数组(例如:C++ 中的 vector 或Java的arraylist ),因为它们显着减少了行数和工作负载。

下面是上述方法的实现:

C++
// C++ program to merge K sorted arrays of
// different arrays
  
#include 
#include 
using namespace std;
  
// Function to merge two arrays
vector mergeTwoArrays(vector l, vector r)
{ 
    // array to store the result
    // after merging l and r
    vector 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 mergeArrays(vector > arr)
{
    // 2D-array to store the results of
    // a step temporarily
    vector > 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 > arr{ { 3, 13 },
                              { 8, 10, 11 },
                              { 9, 15 } };
    // Merged sorted array
    vector output = mergeArrays(arr);
  
    for (int i = 0; i < output.size(); i++)
        cout << output[i] << " ";
  
    return 0;
}


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


输出:
3 8 9 10 11 13 15

请注意,存在使用堆(或优先级队列)的更好解决方案。基于堆的解决方案的时间复杂度为 O(N Log k),其中 N 是所有 K 个数组中的元素总数。