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, 10, 15, 20};
       ar2[] = {2, 3, 8, 13};
Output: ar1[] = {1, 2, 3, 5, 8, 9}
        ar2[] = {10, 13, 15, 20} 

We have discussed a quadratic time solution in below post.
Merge two sorted arrays with O(1) extra space

In this post a better solution is discussed.

The idea: we start comparing elements that are far from each other rather than adjacent.
For every pass, we calculate the gap and compare the elements towards the right of the gap. Every pass, the gap reduces to the ceiling value of dividing by 2.

Examples:

First example: a1[] = {3 27 38 43}, a2[] = {9 10 82}
Start with gap =  ceiling of n/2 = 4 [This gap is for 
                                  whole merged array]
        3 27 38 43   9 10 82 
        3 27 38 43   9 10 82
        3 10 38 43   9 27 82
        gap = 2:
        3 10 38 43   9 27 82
        3 10 38 43   9 27 82
        3 10 38 43   9 27 82 
        3 27 9 10   38 43 82
        3 27 9 10   38 43 82
        gap = 1:
        3 27 9 10   38 43 82
        3 27 9 10   38 43 82
        3 9 27 10   38 43 82
        3 9 10 27   38 43 82
        3 9 10 27   38 43 82
        3 9 10 27   38 43 82
Output : 3 9 10 27 38 43 82

Second Example: a1[] = {10 27 38 43 82}, a2[] = {3 9}
Start with gap = ceiling of n/2 (4):
10 27 38 43 82   3 9 
10 27 38 43 82   3 9
10 3 38 43 82   27 9
10 3 9 43 82   27 38
gap = 2:
10 3 9 43 82   27 38
9 3 10 43 82   27 38
9 3 10 43 82   27 38
9 3 10 43 82   27 38
9 3 10 27 82   43 38
9 3 10 27 38   43 82
gap = 1
9 3 10 27 38   43 82
3 9 10 27 38   43 82
3 9 10 27 38   43 82
3 9 10 27 38   43 82
3 9 10 27 38   43 82
3 9 10 27 38   43 82
Output : 3 9 10 27 38   43 82

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// Merging two sorted arrays with O(1)
// extra space
#include <bits/stdc++.h>
using namespace std;
  
// Function to find next gap.
int nextGap(int gap)
{
    if (gap <= 1)
        return 0;
    return (gap / 2) + (gap % 2);
}
  
void merge(int *arr1, int *arr2, int n, int m)
{
    int i, j, gap = n + m;
    for (gap = nextGap(gap); gap > 0; gap = nextGap(gap))
    {
        // comparing elements in the first array.
        for (i = 0; i + gap < n; i++)
            if (arr1[i] > arr1[i + gap])
                swap(arr1[i], arr1[i + gap]);
  
        //comparing elements in both arrays.
        for (j = gap > n ? gap-n : 0 ; i < n&&j < m; i++, j++)
            if (arr1[i] > arr2[j])
                swap(arr1[i], arr2[j]);
  
        if (j < m)
        {
            //comparing elements in the second array.
            for (j = 0; j + gap < m; j++)
                if (arr2[j] > arr2[j + gap])
                    swap(arr2[j], arr2[j + gap]);
        }
    }
}
  
// Driver code
int main()
{
    int a1[] = { 10, 27, 38, 43 ,82 };
    int a2[] = { 3,9 };
    int n = sizeof(a1) / sizeof(int);
    int m = sizeof(a2) / sizeof(int);
  
    merge(a1, a2, n, m);
  
    printf("First Array: ");
    for (int i = 0; i < n; i++)
        printf("%d ", a1[i]);
  
    printf("\nSecond Array: ");
    for (int i = 0; i < m; i++)
        printf("%d ", a2[i]);
    printf("\n");
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for Merging two sorted arrays 
// with O(1) extra space
  
public class MergeTwoSortedArrays {
  
    // Function to find next gap.
    private static int nextGap(int gap)
    {
        if (gap <= 1)
            return 0;
        return (gap / 2) + (gap % 2);
    }
  
    private static void merge(int[] arr1, int[] arr2,
                              int n, int m) {
        int i, j, gap = n + m;
        for (gap = nextGap(gap); gap > 0;
             gap = nextGap(gap))
        {
            // comparing elements in the first 
            // array.
            for (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;
                }
  
            // comparing elements in both arrays.
            for (j = gap > n ? gap - n : 0
                 i < n && j < m; i++, j++)
                if (arr1[i] > arr2[j]) {
                    int temp = arr1[i];
                    arr1[i] = arr2[j];
                    arr2[j] = temp;
                }
  
            if (j < m)
            {
                // comparing elements in the 
                // second array.
                for (j = 0; j + gap < m; j++)
                    if (arr2[j] > arr2[j + gap]) {
                        int temp = arr2[j];
                        arr2[j] = arr2[j + gap];
                        arr2[j+gap] = temp;
                    }
            }
        }
    }
  
    public static void main(String[] args) {
        int[] a1 = { 10, 27, 38, 43 ,82 };
        int[] a2 = { 3,9 };
  
        merge(a1, a2, a1.length, a2.length);
  
        System.out.print("First Array: ");
        for (int i = 0; i < a1.length; i++) {
            System.out.print(a1[i] + " ");
        }
          
        System.out.println();
          
        System.out.print("Second Array: ");
        for (int i = 0; i < a2.length; i++) {
            System.out.print(a2[i] + " ");
        }
    }
}
  
 // This code is contributed by Vinisha Shah

chevron_right


Python 3

# Merging two sorted arrays with O(1)
# extra space

# Function to find next gap.
def nextGap( gap):

if (gap <= 1): return 0 return (gap // 2) + (gap % 2) def merge(arr1, arr2, n, m): gap = n + m gap = nextGap(gap) 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

#comparing elements in both arrays.
j = gap – n if gap > n else 0
while i < n and j < m: if (arr1[i] > arr2[j]):
arr1[i], arr2[j] = arr2[j], arr1[i]

i += 1
j += 1

if (j < m): # comparing elements in the # second array. j = 0 while j + gap < m : if (arr2[j] > arr2[j + gap]):
arr2[j], arr2[j + gap] = arr2[j + gap], arr2[j]

j += 1

gap = nextGap(gap)

# Driver code
if __name__ == “__main__”:

a1 = [ 10, 27, 38, 43 ,82 ]
a2 = [ 3, 9 ]
n = len(a1)
m = len(a2)

merge(a1, a2, n, m)

print(“First Array: “, end = “”)
for i in range(n):
print(a1[i], end = ” “)
print()

print(“Second Array: “, end = “”)
for i in range(m):
print(a2[i], end = ” “)
print()

# This code is contributed
# by ChitraNayal

C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for Merging two sorted arrays 
// with O(1) extra space
using System;
  
class GFG {
  
    // Function to find next gap.
    static int nextGap(int gap)
    {
        if (gap <= 1)
            return 0;
        return (gap / 2) + (gap % 2);
    }
  
    private static void merge(int[] arr1,
                 int[] arr2, int n, int m)
    {
        int i, j, gap = n + m;
        for (gap = nextGap(gap); gap > 0;
            gap = nextGap(gap))
        {
            // comparing elements in the first 
            // array.
            for (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;
                }
  
            // comparing elements in both arrays.
            for (j = gap > n ? gap - n : 0 ; 
                i < n && j < m; i++, j++)
                if (arr1[i] > arr2[j]) {
                    int temp = arr1[i];
                    arr1[i] = arr2[j];
                    arr2[j] = temp;
                }
  
            if (j < m)
            {
                // comparing elements in the 
                // second array.
                for (j = 0; j + gap < m; j++)
                    if (arr2[j] > arr2[j + gap])
                    {
                        int temp = arr2[j];
                        arr2[j] = arr2[j + gap];
                        arr2[j+gap] = temp;
                    }
            }
        }
    }
  
    // Driver code
    public static void Main()
    {
        int[] a1 = { 10, 27, 38, 43 ,82 };
        int[] a2 = { 3,9 };
  
        merge(a1, a2, a1.Length, a2.Length);
  
        Console.Write("First Array: ");
        for (int i = 0; i < a1.Length; i++) {
            Console.Write(a1[i] + " ");
        }
          
        Console.WriteLine();
          
        Console.Write("Second Array: ");
        for (int i = 0; i < a2.Length; i++) {
            Console.Write(a2[i] + " ");
        }
    }
}
  
// This code is contributed by Sam007.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// Merging two sorted arrays 
// with O(1) extra space
  
// Function to find next gap.
function nextGap($gap)
{
    if ($gap <= 1)
        return 0;
    return ($gap / 2) + 
           ($gap % 2);
}
  
function merge($arr1, $arr2
               $n, $m)
{
    $i;
    $j
    $gap = $n + $m;
    for ($gap = nextGap($gap); 
         $gap > 0; $gap = nextGap($gap))
    {
        // comparing elements 
        // in the first array.
        for ($i = 0; $i + $gap < $n; $i++)
            if ($arr1[$i] > $arr1[$i + $gap])
            {
                $tmp = $arr1[$i];
                $arr1[$i] = $arr1[$i + $gap];
                $arr1[$i + $gap] = $tmp;
            }
  
        // comparing elements 
        // in both arrays.
        for ($j = $gap > $n ? $gap - $n : 0 ; 
             $i < $n && $j < $m; $i++, $j++)
            if ($arr1[$i] > $arr2[$j])
            {
                $tmp = $arr1[$i];
                $arr1[$i] = $arr2[$j];
                $arr2[$j] = $tmp;
            }
  
        if ($j < $m)
        {
            // comparing elements in
            // the second array.
            for ($j = 0; $j + $gap < $m; $j++)
                if ($arr2[$j] > $arr2[$j + $gap])
                {
                    $tmp = $arr2[$j];
                    $arr2[$j] = $arr2[$j + $gap];
                    $arr2[$j + $gap] = $tmp;
                }
        }
    }
      
    echo "First Array: ";
    for ($i = 0; $i < $n; $i++)
        echo $arr1[$i]." ";
  
    echo "\nSecond Array: ";
    for ($i = 0; $i < $m; $i++)
        echo $arr2[$i] . " ";
    echo"\n";
  
}
  
// Driver code
$a1 = array(10, 27, 38, 43 ,82);
$a2 = array(3,9);
$n = sizeof($a1);
$m = sizeof($a2);
  
merge($a1, $a2, $n, $m);
  
// This code is contributed 
// by mits.
?>

chevron_right



Output:

First Array: 3 9 10 27 38
Second Array: 43 82

This article is contributed by Shlomi Elhaiani. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : Sam007, Mithun Kumar, Ita_c