文章目录
0. 题目相关
【题目解读】
给定两个有序数组,对数组进行合并操作。要求合并后的数组依旧有序。
【原题描述】原题链接
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note:
The number of elements initialized in nums1 and nums2 are m and n respectively.
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.
Example:
Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
【难度】Easy
1. Solution
题目挺简单的,两个都是有序的,所以这里想到了最简单便捷的方法,先将数组2放到数组1的最后,再对相加后的数组进行排序操作。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums1.size() < m + n)
{
return;
}
vector<int>::iterator it = nums1.begin();
//指针指到有效的最后一位
it = it + m;
for(int i = 0; i < n; i++)
{
*it++ = nums2[i];
}
sort(nums1.begin(), nums1.begin() + m + n);
}
};
代码提交情况:
其他版本代码:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums1.size() < m + n)
{
return;
}
vector<int>::iterator it = nums1.begin();
nums1.insert(it+m, nums2.begin(), nums2.begin() + n); //直接进行插入操作
nums1.erase(nums1.begin()+m+n,nums1.begin()+m+n+n); //删除多的元素
sort(nums1.begin(), nums1.begin() + m + n);
}
};
上述代码提交结果:
2. 其他改进方案
如果从前面开始操作,中间比较将会进行多次移位操作,此时带来了巨大的内存开销。
由于是两个有序数组,此时可以充分利用有序这一点。据此可以获知,最终的序列中,最大的一个数值不是来自于nums1的最后一个,就是来自于nums2的最后一个,所以可以利用这一点特性,从两个数组的最后一个数据进行比较,避免多次移位操作,就只用比较一次就可以把数据放到最终位置。
实现代码:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums1.size() < m + n)
{
return;
}
int i = m - 1; //nums1的最后一个有效元素的下标
int j = n - 1; //nums2的最后一个下标
int end = m + n - 1;
while(i >= 0 && j >= 0)
{
if(nums1[i] >= nums2[j])
{
nums1[end--] = nums1[i--];
}else
{
nums1[end--] = nums2[j--];
}
}
//以下两个while代码只会执行一个
while(i >= 0)
{
nums1[end--] = nums1[i--];
}
while(j >= 0)
{
nums1[end--] = nums2[j--];
}
}
};
评估结果:
另,上述代码中,两个while只执行一个部分,这里实际上还可以进行优化,可以删除 while(i >= 0)
的处理,因为此时end就是i了,这里的操作相当于是自己给自己赋值。所以最终的代码为:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums1.size() < m + n)
{
return;
}
int i = m - 1; //nums1的最后一个有效元素的下标
int j = n - 1; //nums2的最后一个下标
int end = m + n - 1;
while(i >= 0 && j >= 0)
{
if(nums1[i] >= nums2[j])
{
nums1[end--] = nums1[i--];
}else
{
nums1[end--] = nums2[j--];
}
}
while(j >= 0)
{
nums1[end--] = nums2[j--];
}
}
};