Skip to content
Related Articles

Related Articles

Merge two sorted arrays with O(1) extra space
  • Difficulty Level : Medium
  • Last Updated : 06 Apr, 2021
GeeksforGeeks - Summer Carnival Banner

We are given two sorted arrays. We need to merge these two arrays such that the initial numbers (after complete sorting) are in the first array and the remaining numbers are in the second array. Extra space allowed in O(1).

Example: 

Input: ar1[] = {10};
       ar2[] = {2, 3};
Output: ar1[] = {2}
        ar2[] = {3, 10}  

Input: ar1[] = {1, 5, 9, 10, 15, 20};
       ar2[] = {2, 3, 8, 13};
Output: ar1[] = {1, 2, 3, 5, 8, 9}
        ar2[] = {10, 13, 15, 20}

This task is simple and O(m+n) if we are allowed to use extra space. But it becomes really complicated when extra space is not allowed and doesn’t look possible in less than O(m*n) worst case time.  Though further optimizations are possible
The idea is to begin from last element of ar2[] and search it in ar1[]. If there is a greater element in ar1[], then we move last element of ar1[] to ar2[]. To keep ar1[] and ar2[] sorted, we need to place last element of ar2[] at correct place in ar1[]. We can use Insertion Sort type of insertion for this. 

1. Method 1

Algorithm: 



1) Iterate through every element of ar2[] starting from last 
   element. Do following for every element ar2[i]
    a) Store last element of ar1[i]: last = ar1[i]
    b) Loop from last element of ar1[] while element ar1[j] is 
       greater than ar2[i].
          ar1[j+1] = ar1[j] // Move element one position ahead
          j--
    c) If any element of ar1[] was moved or (j != m-1)
          ar1[j+1] = ar2[i] 
          ar2[i] = last

In above loop, elements in ar1[] and ar2[] are always kept sorted.

Below is the implementation of above algorithm. 

C++




// C++ program to merge two sorted
//  arrays with O(1) extra space.
#include <bits/stdc++.h>
using namespace std;
 
// Merge ar1[] and ar2[] with O(1) extra space
void merge(int ar1[], int ar2[], int m, int n)
{
    // Iterate through all elements
    // of ar2[] starting from the last element
    for (int i = n - 1; i >= 0; i--)
    {
        /* Find the smallest element greater than ar2[i].
        Move all elements one position ahead till the
        smallest greater element is not found */
        int j, last = ar1[m - 1];
        for (j = m - 2; j >= 0
             && ar1[j] > ar2[i]; j--)
            ar1[j + 1] = ar1[j];
 
        // If there was a greater element
        if (j != m - 2 || last > ar2[i])
        {
            ar1[j + 1] = ar2[i];
            ar2[i] = last;
        }
    }
}
 
// Driver program
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]);
    merge(ar1, ar2, m, 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




// Java program program to merge two
// sorted arrays with O(1) extra space.
 
import java.util.Arrays;
 
class Test
{
    static int arr1[] = new int[]{1, 5, 9, 10, 15, 20};
    static int arr2[] = new int[]{2, 3, 8, 13};
     
    static void merge(int m, int n)
    {
        // Iterate through all elements of ar2[] starting from
        // the last element
        for (int i=n-1; i>=0; i--)
        {
            /* Find the smallest element greater than ar2[i]. Move all
               elements one position ahead till the smallest greater
               element is not found */
            int j, last = arr1[m-1];
            for (j=m-2; j >= 0 && arr1[j] > arr2[i]; j--)
                arr1[j+1] = arr1[j];
      
            // If there was a greater element
            if (j != m-2 || last > arr2[i])
            {
                arr1[j+1] = arr2[i];
                arr2[i] = last;
            }
        }
    }
     
    // Driver method to test the above function
    public static void main(String[] args)
    {
        merge(arr1.length,arr2.length);
        System.out.print("After Merging nFirst Array: ");
        System.out.println(Arrays.toString(arr1));
        System.out.print("Second Array:  ");
        System.out.println(Arrays.toString(arr2));
    }
}

Python3




# Python program to merge
# two sorted arrays
# with O(1) extra space.
 
# Merge ar1[] and ar2[]
# with O(1) extra space
def merge(ar1, ar2, m, n):
 
    # Iterate through all
    # elements of ar2[] starting from
    # the last element
    for i in range(n-1, -1, -1):
     
        # Find the smallest element
        # greater than ar2[i]. Move all
        # elements one position ahead
        # till the smallest greater
        # element is not found
        last = ar1[m-1]
        j=m-2
        while(j >= 0 and ar1[j] > ar2[i]):
            ar1[j+1] = ar1[j]
            j-=1
  
        # If there was a greater element
        if (j != m-2 or last > ar2[i]):
         
            ar1[j+1] = ar2[i]
            ar2[i] = last
  
# Driver program
 
ar1 = [1, 5, 9, 10, 15, 20]
ar2 = [2, 3, 8, 13]
m = len(ar1)
n = len(ar2)
 
merge(ar1, ar2, m, n)
  
print("After Merging \nFirst Array:", end="")
for i in range(m):
    print(ar1[i] , " ", end="")
 
print("\nSecond Array: ", end="")
for i in range(n):
    print(ar2[i] , " ", end="")
 
# This code is contributed
# by Anant Agarwal.

C#




// C# program program to merge two
// sorted arrays with O(1) extra space.
using System;
 
// Java program program to merge two
// sorted arrays with O(1) extra space.
 
 
public class Test
{
    static int []arr1 = new int[]{1, 5, 9, 10, 15, 20};
    static int []arr2 = new int[]{2, 3, 8, 13};
     
    static void merge(int m, int n)
    {
        // Iterate through all elements of ar2[] starting from
        // the last element
        for (int i=n-1; i>=0; i--)
        {
            /* Find the smallest element greater than ar2[i]. Move all
            elements one position ahead till the smallest greater
            element is not found */
            int j, last = arr1[m-1];
            for (j=m-2; j >= 0 && arr1[j] > arr2[i]; j--)
                arr1[j+1] = arr1[j];
     
            // If there was a greater element
            if (j != m-2 || last > arr2[i])
            {
                arr1[j+1] = arr2[i];
                arr2[i] = last;
            }
        }
    }
     
    // Driver method to test the above function
    public static void Main()
    {
        merge(arr1.Length,arr2.Length);
        Console.Write("After Merging \nFirst Array: ");
        for(int i =0; i< arr1.Length;i++){
            Console.Write(arr1[i]+" ");
        }
        Console.Write("\nSecond Array: ");
        for(int i =0; i< arr2.Length;i++){
            Console.Write(arr2[i]+" ");
        }
    }
}
 
/*This code is contributed by 29AjayKumar*/

PHP




<?php
// PHP program to merge two sorted arrays with O(1) extra space.
  
// Merge ar1[] and ar2[] with O(1) extra space
function merge(&$ar1, &$ar2, $m, $n)
{
    // Iterate through all elements of ar2[] starting from
    // the last element
    for ($i = $n-1; $i >= 0; $i--)
    {
        /* Find the smallest element greater than ar2[i]. Move all
           elements one position ahead till the smallest greater
           element is not found */
        $last = $ar1[$m-1];
        for ($j = $m-2; $j >= 0 && $ar1[$j] > $ar2[$i]; $j--)
            $ar1[$j+1] = $ar1[$j];
  
        // If there was a greater element
        if ($j != $m-2 || $last > $ar2[$i])
        {
            $ar1[$j+1] = $ar2[$i];
            $ar2[$i] = $last;
        }
    }
}
  
// Driver program
 
$ar1 = array(1, 5, 9, 10, 15, 20);
$ar2 = array(2, 3, 8, 13);
$m = sizeof($ar1)/sizeof($ar1[0]);
$n = sizeof($ar2)/sizeof($ar2[0]);
merge($ar1, $ar2, $m, $n);
 
echo "After Merging \nFirst Array: ";
for ($i=0; $i<$m; $i++)
    echo $ar1[$i] . " ";
echo "\nSecond Array: ";
for ($i=0; $i<$n; $i++)
    echo $ar2[$i] ." ";
return 0;
?>

Javascript




<script>
 
// Javascript program program to merge two
// sorted arrays with O(1) extra space.
 
    let arr1=[1, 5, 9, 10, 15, 20];
    let arr2=[2, 3, 8, 13];
     
    function merge(m,n)
    {
        // Iterate through all elements of ar2[] starting from
        // the last element
        for (let i=n-1; i>=0; i--)
        {
            /* Find the smallest element greater than ar2[i]. Move all
               elements one position ahead till the smallest greater
               element is not found */
            let j, last = arr1[m-1];
            for (j=m-2; j >= 0 && arr1[j] > arr2[i]; j--)
                arr1[j+1] = arr1[j];
       
            // If there was a greater element
            if (j != m-2 || last > arr2[i])
            {
                arr1[j+1] = arr2[i];
                arr2[i] = last;
            }
        }
    }
     
    // Driver method to test the above function
    merge(arr1.length,arr2.length);
    document.write("After Merging <br>First Array: ");
    for(let i=0;i<arr1.length;i++)
    {
        document.write(arr1[i]+" ");
    }
    document.write("<br>Second Array:  ");
    for(let i=0;i<arr2.length;i++)
    {
        document.write(arr2[i]+" ");
    }
     
     
    //  This code is contributed by avanitrachhadiya2155
     
</script>

Output: 

After Merging 
First Array: 1 2 3 5 8 9 
Second Array: 10 13 15 20

Time Complexity: The worst case time complexity of code/algorithm is O(m*n). The worst case occurs when all elements of ar1[] are greater than all elements of ar2[].

Illustration: 
 

merge-two-sorted-arrays

<!— Initial Arrays: 
ar1[] = {1, 5, 9, 10, 15, 20}; 
ar2[] = {2, 3, 8, 13};
After First Iteration: 
ar1[] = {1, 5, 9, 10, 13, 15}; 
ar2[] = {2, 3, 8, 20}; 
// 20 is moved from ar1[] to ar2[] 
// 13 from ar2[] is inserted in ar1[]
After Second Iteration: 
ar1[] = {1, 5, 8, 9, 10, 13}; 
ar2[] = {2, 3, 15, 20}; 
// 15 is moved from ar1[] to ar2[] 
// 8 from ar2[] is inserted in ar1[]
After Third Iteration: 
ar1[] = {1, 3, 5, 8, 9, 10}; 
ar2[] = {2, 13, 15, 20}; 
// 13 is moved from ar1[] to ar2[] 
// 3 from ar2[] is inserted in ar1[]
After Fourth Iteration: 
ar1[] = {1, 2, 3, 5, 8, 9}; 
ar2[] = {10, 13, 15, 20}; 
// 10 is moved from ar1[] to ar2[] 
// 2 from ar2[] is inserted in ar1[] 
—!>
 

Method 2:



The solution can be further optimized by observing that while traversing the two sorted arrays parallelly, if we encounter the jth second array element is smaller than ith first array element, then jth element is to be included and replace some kth element in the first array. This observation helps us with the following algorithm

Algorithm

1) Initialize i,j,k as 0,0,n-1 where n is size of arr1 
2) Iterate through every element of arr1 and arr2 using two pointers i and j respectively
    if arr1[i] is less than arr2[j]
        increment i
    else
        swap the arr2[j] and arr1[k]
        increment j and decrement k

3) Sort both arr1 and arr2 

Below is the implementation of above algorithm

C++




// CPP program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to merge two arrays
void merge(int arr1[], int arr2[], int n, int m)
{
    int i = 0, j = 0, k = n - 1;
   
    // Untill i less than equal to k
    // or j is less tha m
    while (i <= k and j < m) {
        if (arr1[i] < arr2[j])
            i++;
        else {
            swap(arr2[j++], arr1[k--]);
        }
    }
   
    // Sort first array
    sort(arr1, arr1 + n);
   
    // Sort second array
    sort(arr2, arr2 + 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]);
    merge(ar1, ar2, m, 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




// Java program for the above approach
import java.util.Arrays;
import java.util.Collections;
 
class GFG {
    static int arr1[] = new int[] { 1, 5, 9, 10, 15, 20 };
    static int arr2[] = new int[] { 2, 3, 8, 13 };
 
    // Function to merge two arrays
    static void merge(int m, int n)
    {
        int i = 0, j = 0, k = n - 1;
        while (i <= k and j < m) {
            if (arr1[i] < arr2[j])
                i++;
            else {
                int temp = arr2[j];
                arr2[j] = arr1[k];
                arr1[k] = temp;
                j++;
                k--;
            }
        }
        Arrays.sort(arr1);
        Arrays.sort(arr2);
    }
 
    public static void main(String[] args)
    {
        merge(arr1.length, arr2.length);
        System.out.print("After Merging \nFirst Array: ");
        System.out.println(Arrays.toString(arr1));
        System.out.print("Second Array:  ");
        System.out.println(Arrays.toString(arr2));
    }
}

Output

After Merging 
First Array: 1 2 3 5 8 9
Second Array: 10 13 15 20

Complexities:

Time Complexity: The time complexity while traversing the arrays in while loop is O(n+m) in worst case and sorting is O(nlog(n) + mlog(m)). So overall time complexity of the code becomes O((n+m)log(n+m)).

Space Complexity: As the function doesn’t use any extra array for any operations, the space complexity is O(1).

Efficiently merging two sorted arrays with O(1) extra space
 
Related Articles : 
Merge two sorted arrays 
Merge k sorted arrays | Set 1
Thanks to Shubham Chauhan for suggesting 1st solution and Himanshu Kaushik for the 2nd solution. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :