18

We have an array of size m+n in which m elements are present, in sorted order, and a second array of size n, again in sorted order. We want both of them to be sorted and present in the first array. No third array is supposed to be given.

Example:

   1, 3, 55, 66, 77, _, _, _ 
   5, 9, 20 

The answer would be:

   1, 3, 5, 9, 20, 55, 66, 77 
Svante
  • 50,694
  • 11
  • 78
  • 122
algo-geeks
  • 5,280
  • 10
  • 42
  • 54
  • 2
    So use a merge sort. And the question is? – Pete Kirkham Dec 29 '10 at 09:59
  • @Mark Byers no, it's not a dupe of that as this has n extra storage rather than being truly in-place – Pete Kirkham Dec 29 '10 at 10:00
  • This is not really an in-place merge. This is just a merge into the first array, which can be implemented by many algorithms, from trivial and dummy (like insertion sort) to more complicated. In-place merge is a classic problem that implies that both sub-arrays are initially stored in the first array. – AnT stands with Russia Jun 04 '13 at 04:11

4 Answers4

30

Do a regular merge sort but in reverse comparing the largest numbers first, storing (reversed) into the end of the first array going backwards. This way, the elements you're merging are never overwritten (that this works is easy to see if you think about it for a moment).

  • 5
    Nice answer. "Do a regular merge sort" remove "sort" from your answer. Its confusing people. – Mangoose Aug 15 '15 at 12:32
  • Thanks, this problem finally clicked after reading your answer. I was wondering how elements weren't being overwritten, and finally seeing somebody at least acknowledge that it would be an issue got me to figure out how it works. Hah. – JHS Dec 22 '18 at 22:06
2
    // merge the elements in B[] to A[], starting from the last one
    void merge(int A[], int m, int B[], int n) {
       // m-1 and n-1 represent the current element index in A[] and B[] respectively
      while (n > 0) { // there are still elements in B[] not merged
          if (m > 0 && A[m-1] > B[n-1]) { // current element in A[] > current element in B[]
            A[m+n-1] = A[m-1]; // move current element of A[] to its right position
            --m; // decrease current element index of A[]
          }
         else { // current element in A[] <= current element in B[]
            A[m+n-1] = B[n-1]; // move current element in B[] to its right position
            --n; // decrease current element index of B[]
         }
      }
   }
Yanling
  • 303
  • 2
  • 9
1

In-place basically requires we only use "constant" amount of memory, which does not change with different input array sizes. However, the question itself allocate extra amount of memory that is the same to the size of one of the two input arrays, which is O(n) memory in worst case. This basically makes the idea of "in-place" meaningless...

The question might be better phrased as "merge without extra memory", which is a more precise description of its real intention...

1

Move the contents of the first array to the end of the first array, such that the empty elements are now at the beginning. Then merge the two sequences as usual into the first array.

Markus Kull
  • 1,471
  • 13
  • 16
  • what is the need to shift the elements to the end of first array.rather we can start comparison of elements from end of two array and will place the elements in the end of first array. – algo-geeks Dec 29 '10 at 10:11
  • @prp your proposal should work too and is propably easier. i was just used to merging by selecting the smaller. – Markus Kull Dec 29 '10 at 10:18