notes/OJ notes/pages/Leetcode Merge-Sorted-Array.md
2022-09-06 20:22:48 +08:00

178 lines
4.4 KiB
Markdown

# 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;
}
}
}
```