# Leetcode Merge-Sorted-Array

#### 2022-06-10

---

##### Data structures:

#DS #set #multiset #vector

##### Algorithms:

#algorithm #merge_sort #two_pointers

##### Difficulty:

#leetcode #coding_problem #difficulty-easy

##### Related topics:

##### Links:

- [Link to problem](https://leetcode.com/problems/merge-sorted-array/)
- [multiset cpp reference](https://leetcode.com/problems/merge-sorted-array/)

---

### Problem

You are given two integer arrays `nums1` and `nums2`, sorted in **non-decreasing order**, and two integers `m` and `n`, representing the number of elements in `nums1` and `nums2` respectively.

**Merge** `nums1` and `nums2` into a single array sorted in **non-decreasing order**.

The final sorted array should not be returned by the function, but instead be _stored inside the array_ `nums1`. To accommodate this, `nums1` has a length of `m + n`, where the first `m` elements denote the elements that should be merged, and the last `n` elements are set to `0` and should be ignored. `nums2` has a length of `n`.

#### Examples

Example 1:

```
Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Explanation: The arrays we are merging are [1,2,3] and [2,5,6].
The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1.
```

Example 2:

```
Input: nums1 = [1], m = 1, nums2 = [], n = 0
Output: [1]
Explanation: The arrays we are merging are [1] and [].
The result of the merge is [1].
```

Example 3:

```
Input: nums1 = [0], m = 0, nums2 = [1], n = 1
Output: [1]
Explanation: The arrays we are merging are [] and [1].
The result of the merge is [1].
Note that because m = 0, there are no elements in nums1. The 0 is only there to ensure the merge result can fit in nums1.
```

#### Constraints

- nums1.length == m + n
- nums2.length == n
- 0 <= m, n <= 200
- 1 <= m + n <= 200
- -10E9 <= nums1[i], nums2[j] <= 10E9

### Thoughts

I have came up with three ways.
The first one is to use **Merge Sort**, which is fast but slow to implement.
And second one is cpp's **[[cpp_std_multiset]]**, which is O(nlog(n))
Lastly, use the two pointer apporach, which is O(n)

The second one can be **optimized**, by using [This approach](https://leetcode.com/problems/merge-sorted-array/discuss/2120436/0ms-Solution-in-C++-using-two-pointers), which writes directly on num1, since there are whitespaces and unused ones will never get overwritten.

For using cpp, the most difficult thing was actually to use the vector library.

### Solution

multiset solution: O(nlogn)

```cpp
#include <iterator>
#include <set>

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
      multiset<int> mset;
      for (int i = 0; i < m; i++) {
        mset.insert(nums1[i]);
      }
      for (int i = 0; i < n; i++) {
        mset.insert(nums2[i]);
      }

      // write answer
      auto it = mset.begin();
      for (int i = 0; i < m + n; i++) {
        nums1[i] = *it;
        it++;
      }
    }
};
```

double pointer solution: O(m+n) (In c, it will get slower, since vectors are more efficient at inserting.)

```cpp
#include <iterator>
#include <vector>

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
      int slowPtr = 0;

      // Because insert will create space for us.
      for (int i = 0; i < n; i++) {
        nums1.pop_back();
      }

      for (auto i = nums1.begin(); i < n + m + nums1.begin(); i++) {
        if (slowPtr < n) {
          if (*i >= nums2[slowPtr]){
            nums1.insert(i, nums2[slowPtr]);
            slowPtr++;
            i--;
          } else if (i - nums1.begin() == m + slowPtr) { // if we reached the empty space of nums1
            nums1.insert(i, nums2[slowPtr]);
            slowPtr++;
          }
        }
      }
    }
};
```

c solution( not optimized )

```c
void insert(int *arr, int numsSize, int loc, int value) {
  for (int i = numsSize - 1; i > loc; i--) {
    arr[i] = arr[i - 1];
  }
  arr[loc] = value;
}

void merge(int *nums1, int nums1Size, int m, int *nums2, int nums2Size, int n) {
  int loc = 0;
  for (int i = 0; i < nums1Size; i++) {
    if (loc < n) {
      if (nums1[i] < nums2[loc]) {
        if (i == m + loc) {
          insert(nums1, nums1Size, i, nums2[loc]);
          loc++;
        } else {
          continue;
        }
      } else if (nums1[i] >= nums2[loc]) {
        insert(nums1, nums1Size, i, nums2[loc]);
        loc++;
      }
    } else {
      break;
    }
  }
}

```
