Merge two sorted arrays in constant space using Min Heap
Last Updated :
09 Nov, 2023
Given two sorted arrays, we need to merge them with O(1) extra space into a sorted array, when N is the size of the first array, and M is the size of the second array.
Example
:
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}
We had already discussed two more approaches to solve the above problem in constant space:
In this article, one more approach using the concept of the heap data structure is discussed without taking any extra space to merge the two sorted arrays. Below is the detailed approach in steps:
- The idea is to convert the second array into a min-heap first. This can be done in O(M) time complexity.
- After converting the second array to min-heap:
- Start traversing the first array and compare the current element for the first array to top of the created min_heap.
- If the current element in the first array is greater than heap top, swap the current element of the first array with the root of the heap, and heapify the root of the min_heap.
- After performing the above operation for every element of the first array, the first array will now contain first N elements of the sorted merged array.
- Now, the elements remained in the min_heap or the second array are the last M elements of the sorted merged array.
- To arrange them in sorted order, apply in-place heapsort on the second array.
Note
: We have used built-in STL functions available in C++ to convert array to min_heap, sorting the heap etc. It is recommended to read -
Heap in C++ STL | make_heap(), push_heap(), pop_heap(), sort_heap() before moving on to the program. Below is the implementation of the above approach:
CPP14
// C++ program to merge two sorted arrays in
// constant space
#include <bits/stdc++.h>
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<int>());
// 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<int>());
// 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<int>());
}
}
// 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;
}
Java
// Nikunj Sonigara
import java.util.*;
public class Main {
// Function to merge two sorted arrays in constant space
public static void mergeArrays(int[] a, int n, int[] b, int m) {
// Convert the second array into a min heap
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (int value : b) {
minHeap.offer(value);
}
// Start traversing the first array
for (int i = 0; i < n; i++) {
// If the current element is greater than the root of the min heap
if (a[i] > minHeap.peek()) {
// Remove and retrieve the minimum element from the min heap
int min = minHeap.poll();
// Swap the elements
int tmp = a[i];
a[i] = min;
minHeap.offer(tmp);
}
}
// Convert the min heap (second array) back to an array
int index = 0;
while (!minHeap.isEmpty()) {
b[index++] = minHeap.poll();
}
// Sort the second array
Arrays.sort(b);
}
// Driver Code
public static void main(String[] args) {
int[] ar1 = { 1, 5, 9, 10, 15, 20 };
int[] ar2 = { 2, 3, 8, 13 };
int m = ar1.length;
int n = ar2.length;
mergeArrays(ar1, m, ar2, n);
System.out.println("After Merging :- \nFirst Array: " + Arrays.toString(ar1));
System.out.println("Second Array: " + Arrays.toString(ar2));
}
}
Python
# Nikunj Sonigara
import heapq
# Function to merge two sorted arrays in constant space
def mergeArrays(a, n, b, m):
# Convert the second array into a min heap
heapq.heapify(b)
# Start traversing the first array
for i in range(n):
# If the current element is greater than the root of the min heap
if a[i] > b[0]:
# Pop the minimum element from the min heap
min_val = heapq.heappop(b)
# Swap the elements
a[i], min_val = min_val, a[i]
# Push the swapped value back to the min heap
heapq.heappush(b, min_val)
# Sort the second array
heapq.heapify(b) # Convert the min heap back to a heap
b.sort()
# Driver Code
if __name__ == "__main__":
ar1 = [1, 5, 9, 10, 15, 20]
ar2 = [2, 3, 8, 13]
m = len(ar1)
n = len(ar2)
mergeArrays(ar1, m, ar2, n)
print("After Merging :- \nFirst Array: ", ar1)
print("Second Array: ", ar2)
C#
using System;
using System.Collections.Generic;
class MainClass
{
// Function to merge two sorted arrays in constant space
public static void MergeArrays(int[] a, int n, int[] b, int m)
{
// Convert the second array into a SortedSet
SortedSet<int> minHeap = new SortedSet<int>(b);
// Start traversing the first array
for (int i = 0; i < n; i++)
{
// If the current element is greater than the first element in the SortedSet
if (a[i] > minHeap.Min)
{
// Remove and retrieve the minimum element from the SortedSet
int min = minHeap.Min;
minHeap.Remove(min);
// Swap the elements
int tmp = a[i];
a[i] = min;
minHeap.Add(tmp);
}
}
// Convert the SortedSet (second array) back to an array
int index = 0;
foreach (var element in minHeap)
{
b[index++] = element;
}
// Sort the second array
Array.Sort(b);
}
// Driver Code
public static void Main(string[] args)
{
int[] ar1 = { 1, 5, 9, 10, 15, 20 };
int[] ar2 = { 2, 3, 8, 13 };
int m = ar1.Length;
int n = ar2.Length;
MergeArrays(ar1, m, ar2, n);
Console.WriteLine("After Merging :- \nFirst Array: " + string.Join(", ", ar1));
Console.WriteLine("Second Array: " + string.Join(", ", ar2));
}
}
JavaScript
class PriorityQueue {
constructor() {
this.heap = [];
}
offer(value) {
this.heap.push(value);
this.bubbleUp();
}
poll() {
if (this.isEmpty()) {
return null;
}
const root = this.heap[0];
const last = this.heap.pop();
if (this.heap.length > 0) {
this.heap[0] = last;
this.bubbleDown();
}
return root;
}
peek() {
return this.isEmpty() ? null : this.heap[0];
}
isEmpty() {
return this.heap.length === 0;
}
size() {
return this.heap.length;
}
bubbleUp() {
let index = this.heap.length - 1;
while (index > 0) {
const element = this.heap[index];
const parentIndex = Math.floor((index - 1) / 2);
const parent = this.heap[parentIndex];
if (parent <= element) {
break;
}
this.heap[index] = parent;
this.heap[parentIndex] = element;
index = parentIndex;
}
}
bubbleDown() {
let index = 0;
while (true) {
const leftChildIndex = 2 * index + 1;
const rightChildIndex = 2 * index + 2;
let smallest = index;
if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] <
this.heap[smallest]) {
smallest = leftChildIndex;
}
if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] <
this.heap[smallest]) {
smallest = rightChildIndex;
}
if (smallest === index) {
break;
}
const temp = this.heap[index];
this.heap[index] = this.heap[smallest];
this.heap[smallest] = temp;
index = smallest;
}
}
}
function mergeArrays(a, n, b, m) {
const minHeap = new PriorityQueue();
// Convert the second array into a min heap
for (const value of b) {
minHeap.offer(value);
}
// Start traversing the first array
for (let i = 0; i < n; i++) {
// If the current element is greater than the root of the min heap
if (a[i] > minHeap.peek()) {
// Remove and retrieve the minimum element from the min heap
const min = minHeap.poll();
// Swap the elements
const temp = a[i];
a[i] = min;
minHeap.offer(temp);
}
}
// Convert the min heap (second array) back to an array
let index = 0;
while (!minHeap.isEmpty()) {
b[index++] = minHeap.poll();
}
// Sort the second array
b.sort((x, y) => x - y);
}
// Driver Code
function main() {
const ar1 = [1, 5, 9, 10, 15, 20];
const ar2 = [2, 3, 8, 13];
const m = ar1.length;
const n = ar2.length;
mergeArrays(ar1, m, ar2, n);
console.log("After Merging :- \nFirst Array: " + JSON.stringify(ar1));
console.log("Second Array: " + JSON.stringify(ar2));
}
main();
OutputAfter Merging :-
First Array: 1 2 3 5 8 9
Second Array: 10 13 15 20
Time Complexity
: O(N*logM + M*logN)
Auxiliary Space
: O(1)
Similar Reads
Merge two sorted arrays in Python using heapq Given two sorted arrays, the task is to merge them in a sorted manner. Examples: Input : arr1 = [1, 3, 4, 5] arr2 = [2, 4, 6, 8] Output : arr3 = [1, 2, 3, 4, 4, 5, 6, 8] Input : arr1 = [5, 8, 9] arr2 = [4, 7, 8] Output : arr3 = [4, 5, 7, 8, 8, 9] This problem has existing solution please refer Merge
2 min read
Merge k Sorted Arrays Using Min Heap Given k sorted arrays of possibly different sizes, merge them and print the sorted output.Examples:Input: k = 3 arr[][] = { {1, 3}, {2, 4, 6}, {0, 9, 10, 11}} ;Output: 0 1 2 3 4 6 9 10 11 Input: k = 2 arr[][] = { {1, 3, 20}, {2, 4, 6}} ;Output: 1 2 3 4 6 20 We have discussed a solution that works fo
7 min read
Merge Two Sorted Arrays Without Extra Space Given two sorted arrays a[] and b[] of size n and m respectively, the task is to merge both the arrays and rearrange the elements such that the smallest n elements are in a[] and the remaining m elements are in b[]. All elements in a[] and b[] should be in sorted order.Examples: Input: a[] = [2, 4,
15+ min read
Efficiently merging two sorted arrays with O(1) extra space Given two sorted arrays, we need to merge them in O((n+m)*log(n+m)) time with O(1) extra space into a sorted array, when n is the size of the first array, and m is the size of the second array. Example: Input: ar1[] = {10}; ar2[] = {2, 3};Output: ar1[] = {2} ar2[] = {3, 10} Input: ar1[] = {1, 5, 9,
15+ min read
Merge two sorted arrays using Priority queue Given two sorted arrays A[] and B[] of sizes N and M respectively, the task is to merge them in a sorted manner. Examples: Input: A[] = { 5, 6, 8 }, B[] = { 4, 7, 8 }Output: 4 5 6 7 8 8 Input: A[] = {1, 3, 4, 5}, B] = {2, 4, 6, 8} Output: 1 2 3 4 4 5 6 8 Input: A[] = {5, 8, 9}, B[] = {4, 7, 8} Outpu
6 min read