Cover image for Interview Classic 150 Questions P88 Merge Two Sorted Arrays

Interview Classic 150 Questions P88 Merge Two Sorted Arrays


Timeline

timeline

2025-09-27

init

two pointers

Title:

This problem can actually be merged in place, because the last n elements of num1 are 0, so you can merge from back to front. But the code below does not take this into account.
Note std::move, it actually converts the parameter t to an rvalue reference type, does not copy memory, does not release resources, does not call constructors or destructors

1
2
3
4
template <typename T>
typename std::remove_reference<T>::type&& move(T&& t) noexcept {
return static_cast<typename std::remove_reference<T>::type&&>(t);
}

Take std::vectoras an example:

1
2
std::vector<int> a = {1, 2, 3};
std::vector<int> b = std::move(a);

Here: std::move(a) turns a into an rvalue reference. The compiler will choose the vector’s move constructor instead of the copy constructor.
What the move constructor does:

  • Directly ‘steal’ the internal pointer of a and give it to b.
  • Set a’s pointer to null to avoid releasing the same memory during destruction.

So in the end: b holds the data of {1,2,3}. a becomes empty (size()==0, but is still a valid object)

Summary:
nums1 = std::move(vec);

  • Old content is automatically released (done internally by move assignment)
  • New content takes over
  • vec becomes empty
    No need to manually call the destructor.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <vector>
using std::vector;

class Solution {
public:
void merge(vector<int> &nums1, int m, vector<int> &nums2, int n)
{
vector<int> vec;
int i = 0, j = 0;
while (1) {
if (i < m && j < n) {
if (nums1[i] <= nums2[j])
vec.push_back(nums1[i++]);
else
vec.push_back(nums2[j++]);
} else if (i < m && j >= n) {
vec.push_back(nums1[i++]);
} else if (i >= m && j < n) {
vec.push_back(nums2[j++]);
} else {
break;
}
}
nums1 = std::move(vec);
}
};