给定两个排序的数组,当N是第一个数组的大小,而M是第二个数组的大小时,我们需要将它们与O(1)多余的空间合并到一个排序的数组中。
范例:
Input: arr1[] = {10};
arr2[] = {2, 3};
Output: arr1[] = {2}
arr2[] = {3, 10}
Input: arr1[] = {1, 5, 9, 10, 15, 20};
arr2[] = {2, 3, 8, 13};
Output: arr1[] = {1, 2, 3, 5, 8, 9}
arr2[] = {10, 13, 15, 20}
我们已经讨论了在恒定空间中解决上述问题的另外两种方法:
- 合并两个排序的数组,并增加O(1)个空间。
- 有效地合并两个排序的数组,并增加O(1)个额外空间。
在本文中,将讨论使用堆数据结构概念的另一种方法,而无需占用任何额外空间来合并两个排序的数组。
以下是分步进行的详细方法:
- 这个想法是先将第二个数组转换为最小堆。这可以以O(M)时间复杂度完成。
- 将第二个数组转换为min-heap之后:
- 开始遍历第一个数组,并将第一个数组的当前元素与创建的min_heap的顶部进行比较。
- 如果第一个数组中的当前元素大于堆顶部,则将第一个数组中的当前元素与堆的根交换,然后对min_heap的根进行堆化。
- 对第一个数组的每个元素执行上述操作后,第一个数组现在将包含已排序合并数组的前N个元素。
- 现在,保留在min_heap或第二个数组中的元素是排序后的合并数组中的最后M个元素。
- 要按排序顺序排列它们,请在第二个数组上应用就地堆排序。
注意:我们已使用C++中可用的内置STL函数将数组转换为min_heap,对堆进行排序等。建议阅读– C++ STL中的堆| make_heap(),push_heap(),pop_heap(),sort_heap(),然后转到程序。
下面是上述方法的实现:
// C++ program to merge two sorted arrays in
// constant space
#include
using namespace std;
// Function to merge two sorted arrays in
// constant space
void mergeArrays(int* a, int n, int* b, int m)
{
// Convert second array into a min_heap
// using make_heap() STL function [takes O(m)]
make_heap(b, b + m, greater());
// Start traversing the first array
for (int i = 0; i < n; i++) {
// If current element is greater than root
// of min_heap
if (a[i] > b[0]) {
// Pop minimum element from min_heap using
// pop_heap() STL function
// The pop_heap() function removes the minimum element from
// heap and moves it to the end of the container
// converted to heap and reduces heap size by 1
pop_heap(b, b + m, greater());
// Swapping the elements
int tmp = a[i];
a[i] = b[m - 1];
b[m - 1] = tmp;
// Apply push_heap() function on the container
// or array to again reorder it in the
// form of min_heap
push_heap(b, b + m, greater());
}
}
// Convert the second array again into max_heap
// because sort_heap() on min heap sorts the array
// in decreasing order
// This step is [O(m)]
make_heap(b, b + m); // It's a max_heap
// Sort the second array using sort_heap() function
sort_heap(b, b + m);
}
// Driver Code
int main()
{
int ar1[] = { 1, 5, 9, 10, 15, 20 };
int ar2[] = { 2, 3, 8, 13 };
int m = sizeof(ar1) / sizeof(ar1[0]);
int n = sizeof(ar2) / sizeof(ar2[0]);
mergeArrays(ar1, m, ar2, n);
cout << "After Merging :- \nFirst Array: ";
for (int i = 0; i < m; i++)
cout << ar1[i] << " ";
cout << "\nSecond Array: ";
for (int i = 0; i < n; i++)
cout << ar2[i] << " ";
return 0;
}
输出:
After Merging :-
First Array: 1 2 3 5 8 9
Second Array: 10 13 15 20
时间复杂度:O(N * logM + M * logN)
辅助空间:O(1)