📌  相关文章
📜  有效地将两个排序的数组与O(1)额外空间和O(NlogN + MlogM)合并

📅  最后修改于: 2021-05-07 07:12:20             🧑  作者: Mango

给定两个排序的数组arr1 []arr2 [] ,任务是在O(Nlog(N)+ Mlog(M))的时间内将它们合并,并增加O(1)的空间,形成一个排序的数组,其中N是数组的大小。第一数组arr1 []M是第二数组arr2 []的大小。

例子:

方法:本文已经讨论了一种方法。在本文中,将讨论一种甚至有效的方法。

  • 通过将一个阵列中的最高元素与第二个阵列中的最低元素进行比较,形成两个双音阵,以使两个阵列仅包含对两个阵列进行排序后将要位于其中的那些元素。
  • 现在,分别对两个数组进行排序。

下面是上述方法的实现:

C++
// C++ implementation of the approach
  
#include 
using namespace std;
  
// Reducing the gap by a factor of 2
int nextGap(int gap)
{
    if (gap <= 1)
        return 0;
    return (gap / 2) + (gap % 2);
}
  
// Function to merge two sorted
// arrays with O(1) extra space
int mergeTwoSortedArray(int* arr1,
                        int* arr2,
                        int n, int m)
{
    int x = min(n, m);
  
    // Form both arrays to be bitonic
    for (int i = 0; i < x; i++) {
        if (arr1[n - i - 1] > arr2[i])
            swap(arr1[n - i - 1], arr2[i]);
    }
  
    // Now both the arrays conatin the numbers
    // which should be there in the result
    // Sort the array indiviually by inplace algo
    for (int gap = nextGap(n); gap > 0;
         gap = nextGap(gap)) {
  
        // Comparing elements in the first array
        for (int i = 0; i + gap < n; i++)
            if (arr1[i] > arr1[i + gap])
                swap(arr1[i], arr1[i + gap]);
    }
  
    // Sort the second array
    for (int gap = nextGap(m); gap > 0;
         gap = nextGap(gap)) {
  
        // Comparing elements in the second array
        for (int i = 0; i + gap < m; i++)
            if (arr2[i] > arr2[i + gap])
                swap(arr2[i], arr2[i + gap]);
    }
    for (int i = 0; i < n; i++)
        cout << arr1[i] << " ";
    for (int j = 0; j < m; j++)
        cout << arr2[j] << " ";
}
  
// Driver code
int main()
{
    int arr1[] = { 1, 5, 9, 10, 15, 20 };
    int n = sizeof(arr1) / sizeof(int);
    int arr2[] = { 2, 3, 8, 13 };
    int m = sizeof(arr2) / sizeof(int);
  
    mergeTwoSortedArray(arr1, arr2, n, m);
  
    return 0;
}


Java
// Java implementation of the approach 
class GFG 
{
      
    // Reducing the gap by a factor of 2 
    static int nextGap(int gap) 
    { 
        if (gap <= 1) 
            return 0; 
        return (int)((gap / 2) + (gap % 2)); 
    } 
      
    // Function to merge two sorted 
    // arrays with O(1) extra space 
    static void mergeTwoSortedArray(int []arr1, 
                                    int []arr2, 
                                    int n, int m) 
    { 
        int x = Math.min(n, m); 
      
        // Form both arrays to be bitonic 
        for (int i = 0; i < x; i++) 
        { 
            if (arr1[n - i - 1] > arr2[i]) 
            {
                // swap(arr1[n - i - 1], arr2[i]); 
                int temp = arr1[n - i - 1];
                arr1[n - i - 1] = arr2[i];
                arr2[i] = temp;
            }
        } 
      
        // Now both the arrays conatin the numbers 
        // which should be there in the result 
        // Sort the array indiviually by inplace algo 
        for (int gap = nextGap(n); gap > 0; 
            gap = nextGap(gap))
        { 
      
            // Comparing elements in the first array 
            for (int i = 0; i + gap < n; i++) 
                if (arr1[i] > arr1[i + gap])
                {
                    // swap(arr1[i], arr1[i + gap]); 
                    int temp = arr1[i];
                    arr1[i] = arr1[i + gap];
                    arr1[i + gap] = temp;
                }
        } 
      
        // Sort the second array 
        for (int gap = nextGap(m); gap > 0; 
            gap = nextGap(gap)) 
        { 
      
            // Comparing elements in the second array 
            for (int i = 0; i + gap < m; i++) 
                if (arr2[i] > arr2[i + gap])
                {
                    // swap(arr2[i], arr2[i + gap]); 
                    int temp = arr2[i];
                    arr2[i] = arr2[i + gap];
                    arr2[i + gap] = temp;
                }
        } 
        for (int i = 0; i < n; i++) 
            System.out.print(arr1[i] + " "); 
        for (int j = 0; j < m; j++) 
            System.out.print(arr2[j] + " "); 
    } 
      
    // Driver code 
    public static void main (String[] args) 
    { 
        int arr1[] = { 1, 5, 9, 10, 15, 20 }; 
        int n = arr1.length; 
        int arr2[] = { 2, 3, 8, 13 }; 
        int m = arr2.length; 
      
        mergeTwoSortedArray(arr1, arr2, n, m); 
    } 
}
  
// This code is contributed by AnkitRai01


Python3
# Python3 implementation of the approach 
  
# Reducing the gap by a factor of 2 
def nextGap(gap) : 
    if (gap <= 1) :
        return 0; 
    res = (gap // 2) + (gap % 2); 
    return res;
  
# Function to merge two sorted 
# arrays with O(1) extra space 
def mergeTwoSortedArray(arr1, arr2, n, m) : 
  
    x = min(n, m); 
  
    # Form both arrays to be bitonic 
    for i in range(x) :
        if (arr1[n - i - 1] > arr2[i]) :
            arr1[n - i - 1],arr2[i] = arr2[i], arr1[n- i - 1];
  
    # Now both the arrays conatin the numbers 
    # which should be there in the result 
    # Sort the array indiviually by inplace algo 
    gap = nextGap(n);
    while gap > 0 :
          
        # Comparing elements in the first array 
        i = 0;
          
        while i + gap < n : 
              
            if (arr1[i] > arr1[i + gap]) :
                arr1[i], arr1[i + gap] = arr1[i + gap],arr1[i];
                  
            i += 1;
              
        gap = nextGap(gap)
  
    # Sort the second array 
    gap = nextGap(m);
      
    while gap > 0 :
          
        # Comparing elements in the second array 
        i = 0
        while i + gap < m :
            if (arr2[i] > arr2[i + gap]) :
                arr2[i], arr2[i + gap] = arr2[i + gap], arr2[i];
                  
            i += 1;
              
        gap = nextGap(gap)
              
    for i in range(n) : 
        print(arr1[i], end = " ");
          
    for j in range(m) :
        print(arr2[j], end = " "); 
  
# Driver code 
if __name__ == "__main__" : 
  
    arr1 = [ 1, 5, 9, 10, 15, 20 ]; 
    n = len(arr1); 
    arr2 = [ 2, 3, 8, 13 ]; 
    m = len(arr2); 
  
    mergeTwoSortedArray(arr1, arr2, n, m); 
  
# This code is contributed by AnkitRai01


C#
// C# implementation of the approach 
using System;
  
class GFG 
{
      
    // Reducing the gap by a factor of 2 
    static int nextGap(int gap) 
    { 
        if (gap <= 1) 
            return 0; 
        return (int)((gap / 2) + (gap % 2)); 
    } 
      
    // Function to merge two sorted 
    // arrays with O(1) extra space 
    static void mergeTwoSortedArray(int []arr1, 
                                    int []arr2, 
                                    int n, int m) 
    { 
        int x = Math.Min(n, m); 
      
        // Form both arrays to be bitonic 
        for (int i = 0; i < x; i++) 
        { 
            if (arr1[n - i - 1] > arr2[i]) 
            {
                int temp = arr1[n - i - 1];
                arr1[n - i - 1] = arr2[i];
                arr2[i] = temp;
            }
        } 
      
        // Now both the arrays conatin the numbers 
        // which should be there in the result 
        // Sort the array indiviually by inplace algo 
        for (int gap = nextGap(n); gap > 0; 
            gap = nextGap(gap))
        { 
      
            // Comparing elements in the first array 
            for (int i = 0; i + gap < n; i++) 
                if (arr1[i] > arr1[i + gap])
                {
                    int temp = arr1[i];
                    arr1[i] = arr1[i + gap];
                    arr1[i + gap] = temp;
                }
        } 
      
        // Sort the second array 
        for (int gap = nextGap(m); gap > 0; 
            gap = nextGap(gap)) 
        { 
      
            // Comparing elements in the second array 
            for (int i = 0; i + gap < m; i++) 
                if (arr2[i] > arr2[i + gap])
                {
                    int temp = arr2[i];
                    arr2[i] = arr2[i + gap];
                    arr2[i + gap] = temp;
                }
        } 
        for (int i = 0; i < n; i++) 
            Console.Write(arr1[i] + " "); 
        for (int j = 0; j < m; j++) 
            Console.Write(arr2[j] + " "); 
    } 
      
    // Driver code 
    public static void Main() 
    { 
        int []arr1 = { 1, 5, 9, 10, 15, 20 }; 
        int n = arr1.Length; 
        int []arr2 = { 2, 3, 8, 13 }; 
        int m = arr2.Length; 
      
        mergeTwoSortedArray(arr1, arr2, n, m); 
    } 
}
  
// This code is contributed by AnkitRai01


输出:
1 2 3 5 8 9 10 13 15 20

时间复杂度: O(Nlog(N)+ Mlog(M))