178 lines
4.4 KiB
Markdown
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
```
|