📌  相关文章
📜  使用 QuickSort 分区合并 O(1) 额外空间中的两个排序数组

📅  最后修改于: 2021-09-16 10:54:36             🧑  作者: Mango

给定两个已排序的数组,大小为NM 的arr[]brr[] ,任务是合并两个给定数组,使它们形成组合两个数组元素的整数排序序列。

例子:

朴素的方法:请参阅合并两个已排序的数组,了解合并两个给定数组的最简单方法。
时间复杂度: O(N * M)
辅助空间: O(1)

空间优化方法:请参阅合并两个已排序数组与 O(1) 额外空间以合并两个给定数组而不使用任何额外内存。
时间复杂度: O(N * M)
辅助空间: O(1)

Efficient Space Optimized Approach:参考Efficiently merging两个已排序数组与O(1)额外空间来合并两个给定数组而不使用任何额外内存。
时间复杂度: O((N + M) * log(N + M))
辅助空间: O(1)

基于分区的方法:想法是将最终排序数组的(N + 1)元素视为主元元素,并围绕主元元素执行快速排序分区。最后,将最终排序数组的前N 个较小元素存储到数组arr[] 中,并将最终排序数组的最后M 个较大元素以任意顺序存储到数组brr[]中,并分别对这两个数组进行排序。请按照以下步骤解决问题:

  1. 初始化一个变量,比如index来存储最终排序数组的每个元素的索引。
  2. 找到第(N + 1)元素 最终排序的数组作为枢轴元素。
  3. 围绕枢轴元素执行快速排序分区。
  4. 最后,分别对数组arr[]brr[] 进行排序。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
#include 
using namespace std;
 
// Function to perform the partition
// around the pivot element
void partition(int arr[], int N,
               int brr[], int M,
               int Pivot)
{
    // Stores index of each element
    // of the array, arr[]
    int l = N - 1;
 
    // Stores index of each element
    // of the array, brr[]
    int r = 0;
 
    // Traverse both the array
    while (l >= 0 && r < M) {
 
        // If pivot is
        // smaller than arr[l]
        if (arr[l] < Pivot)
            l--;
 
        // If Pivot is
        // greater than brr[r]
        else if (brr[r] > Pivot)
            r++;
 
        // If either arr[l] > Pivot
        // or brr[r] < Pivot
        else {
            swap(arr[l], brr[r]);
            l--;
            r++;
        }
    }
}
 
// Function to merge
// the two sorted array
void Merge(int arr[], int N,
           int brr[], int M)
{
    // Stores index of each element
    // of the array arr[]
    int l = 0;
 
    // Stores index of each element
    // of the array brr[]
    int r = 0;
 
    // Stores index of each element
    // the final sorted array
    int index = -1;
 
    // Stores the pivot element
    int Pivot = 0;
 
    // Traverse both the array
    while (index < N && l < N && r < M) {
 
        if (arr[l] < brr[r]) {
            Pivot = arr[l++];
        }
        else {
            Pivot = brr[r++];
        }
        index++;
    }
 
    // If pivot element is not found
    // or index < N
    while (index < N && l < N) {
        Pivot = arr[l++];
        index++;
    }
 
    // If pivot element is not found
    // or index < N
    while (index < N && r < M) {
        Pivot = brr[r++];
        index++;
    }
 
    // Place the first N elements of
    // the sorted array into arr[]
    // and the last M elements of
    // the sorted array into brr[]
    partition(arr, N, brr,
              M, Pivot);
 
    // Sort both the arrays
    sort(arr, arr + N);
 
    sort(brr, brr + M);
 
    // Print the first N elements
    // in sorted order
    for (int i = 0; i < N; i++)
        cout << arr[i] << " ";
 
    // Print the last M elements
    // in sorted order
    for (int i = 0; i < M; i++)
        cout << brr[i] << " ";
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 5, 9 };
    int brr[] = { 2, 4, 7, 10 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int M = sizeof(brr) / sizeof(brr[0]);
    Merge(arr, N, brr, M);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
 
// Function to perform the partition
// around the pivot element
static void partition(int arr[], int N,
                      int brr[], int M,
                      int Pivot)
{
  // Stores index of each element
  // of the array, arr[]
  int l = N - 1;
 
  // Stores index of each element
  // of the array, brr[]
  int r = 0;
 
  // Traverse both the array
  while (l >= 0 && r < M)
  {
    // If pivot is
    // smaller than arr[l]
    if (arr[l] < Pivot)
      l--;
 
    // If Pivot is
    // greater than brr[r]
    else if (brr[r] > Pivot)
      r++;
 
    // If either arr[l] > Pivot
    // or brr[r] < Pivot
    else
    {
      int t = arr[l];
      arr[l] = brr[r];
      brr[r] = t;
      l--;
      r++;
    }
  }
}
 
// Function to merge
// the two sorted array
static void Merge(int arr[], int N,
                  int brr[], int M)
{
  // Stores index of each element
  // of the array arr[]
  int l = 0;
 
  // Stores index of each element
  // of the array brr[]
  int r = 0;
 
  // Stores index of each element
  // the final sorted array
  int index = -1;
 
  // Stores the pivot element
  int Pivot = 0;
 
  // Traverse both the array
  while (index < N && l < N &&
         r < M)
  {
    if (arr[l] < brr[r])
    {
      Pivot = arr[l++];
    }
    else
    {
      Pivot = brr[r++];
    }
    index++;
  }
 
  // If pivot element is not found
  // or index < N
  while (index < N && l < N)
  {
    Pivot = arr[l++];
    index++;
  }
 
  // If pivot element is not
  // found or index < N
  while (index < N && r < M)
  {
    Pivot = brr[r++];
    index++;
  }
 
  // Place the first N elements of
  // the sorted array into arr[]
  // and the last M elements of
  // the sorted array into brr[]
  partition(arr, N, brr,
            M, Pivot);
 
  // Sort both the arrays
  Arrays.sort(arr);
 
  Arrays.sort(brr);
 
  // Print the first N elements
  // in sorted order
  for (int i = 0; i < N; i++)
    System.out.print(arr[i] + " ");
 
  // Print the last M elements
  // in sorted order
  for (int i = 0; i < M; i++)
    System.out.print(brr[i] + " ");
}
 
// Driver Code
public static void main(String[] args)
{
  int arr[] = {1, 5, 9};
  int brr[] = {2, 4, 7, 10};
  int N = arr.length;
  int M = brr.length;
  Merge(arr, N, brr, M);
}
}
 
// This code is contributed by Amit Katiyar


Python3
# Python3 program to implement
# the above approach
 
# Function to perform the partition
# around the pivot element
def partition(arr, N, brr, M, Pivot):
     
    # Stores index of each element
    # of the array, arr[]
    l = N - 1
     
    # Stores index of each element
    # of the array, brr[]
    r = 0
     
    # Traverse both the array
    while (l >= 0 and r < M):
         
        # If pivot is smaller
        # than arr[l]
        if (arr[l] < Pivot):
            l -= 1
 
        # If Pivot is greater
        # than brr[r]
        elif (brr[r] > Pivot):
            r += 1
 
        # If either arr[l] > Pivot
        # or brr[r] < Pivot
        else:
            arr[l], brr[r] = brr[r], arr[l]
            l -= 1
            r += 1
 
# Function to merge
# the two sorted array
def Merge(arr, N, brr, M):
     
    # Stores index of each element
    # of the array arr[]
    l = 0
 
    # Stores index of each element
    # of the array brr[]
    r = 0
 
    # Stores index of each element
    # the final sorted array
    index = -1
 
    # Stores the pivot element
    Pivot = 0
 
    # Traverse both the array
    while (index < N and l < N and r < M):
        if (arr[l] < brr[r]):
            Pivot = arr[l]
            l += 1
        else:
            Pivot = brr[r]
            r += 1
 
        index += 1
 
    # If pivot element is not found
    # or index < N
    while (index < N and l < N):
        Pivot = arr[l]
        l += 1
        index += 1
 
    # If pivot element is not found
    # or index < N
    while (index < N and r < M):
        Pivot = brr[r]
        r += 1
        index += 1
 
    # Place the first N elements of
    # the sorted array into arr[]
    # and the last M elements of
    # the sorted array into brr[]
    partition(arr, N, brr, M, Pivot)
 
    # Sort both the arrays
    arr = sorted(arr)
 
    brr = sorted(brr)
 
    # Print the first N elements
    # in sorted order
    for i in range(N):
        print(arr[i], end = " ")
 
    # Print the last M elements
    # in sorted order
    for i in range(M):
        print(brr[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 5, 9 ]
    brr = [ 2, 4, 7, 10 ]
    N = len(arr)
    M = len(brr)
     
    Merge(arr, N, brr, M)
 
# This code is contributed by mohit kumar 29


C#
// C# program to implement
// the above approach
using System;
class GFG{
 
// Function to perform the
// partition around the pivot
// element
static void partition(int []arr, int N,
                      int []brr, int M,
                      int Pivot)
{
  // Stores index of each element
  // of the array, []arr
  int l = N - 1;
 
  // Stores index of each element
  // of the array, brr[]
  int r = 0;
 
  // Traverse both the array
  while (l >= 0 && r < M)
  {
    // If pivot is
    // smaller than arr[l]
    if (arr[l] < Pivot)
      l--;
 
    // If Pivot is
    // greater than brr[r]
    else if (brr[r] > Pivot)
      r++;
 
    // If either arr[l] > Pivot
    // or brr[r] < Pivot
    else
    {
      int t = arr[l];
      arr[l] = brr[r];
      brr[r] = t;
      l--;
      r++;
    }
  }
}
 
// Function to merge
// the two sorted array
static void Merge(int []arr, int N,
                  int []brr, int M)
{
  // Stores index of each element
  // of the array []arr
  int l = 0;
 
  // Stores index of each element
  // of the array brr[]
  int r = 0;
 
  // Stores index of each element
  // the readonly sorted array
  int index = -1;
 
  // Stores the pivot element
  int Pivot = 0;
 
  // Traverse both the array
  while (index < N && l < N &&
         r < M)
  {
    if (arr[l] < brr[r])
    {
      Pivot = arr[l++];
    }
    else
    {
      Pivot = brr[r++];
    }
    index++;
  }
 
  // If pivot element is not found
  // or index < N
  while (index < N && l < N)
  {
    Pivot = arr[l++];
    index++;
  }
 
  // If pivot element is not
  // found or index < N
  while (index < N && r < M)
  {
    Pivot = brr[r++];
    index++;
  }
 
  // Place the first N elements of
  // the sorted array into []arr
  // and the last M elements of
  // the sorted array into brr[]
  partition(arr, N, brr,
            M, Pivot);
 
  // Sort both the arrays
    Array.Sort(arr);
    Array.Sort(brr);
 
 
  // Print the first N elements
  // in sorted order
  for (int i = 0; i < N; i++)
    Console.Write(arr[i] + " ");
 
  // Print the last M elements
  // in sorted order
  for (int i = 0; i < M; i++)
    Console.Write(brr[i] + " ");
}
 
// Driver Code
public static void Main(String[] args)
{
  int []arr = {1, 5, 9};
  int []brr= {2, 4, 7, 10};
  int N = arr.Length;
  int M = brr.Length;
  Merge(arr, N, brr, M);
}
}
 
// This code is contributed by shikhasingrajput


输出
1 2 4 5 7 9 10 

时间复杂度: O((N + M)log(N + M))
辅助空间: O(1)

高效的方法:参考合并两个已排序的数组来有效地合并两个给定的数组。
时间复杂度: O(N + M)
辅助空间: O(N + M)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程