合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
提示:
-10^9 <= nums1[i], nums2[i] <= 10^9
nums1.length == m + n
nums2.length == n
我的提交代码
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
vector<int>temp(nums1.begin(),nums1.begin()+ m);
int p1 = 0, p2 = 0, t = 0;
while (p2<n&&t<m)
{
if (nums2[p2] < temp[t]) {
nums1[p1++] = nums2[p2++];
}
else {
nums1[p1++] = temp[t++];
}
while(p2 == n && t<m) {
nums1[p1++]=temp[t++];
}
while (t==m && p2 < n) {
nums1[p1++]=nums2[p2++];
}
}
if (m == 0) {
nums1 = nums2;
}
if (n == 0) {
nums1 = nums1;
}
}
};
我的测试代码
#include<vector>
#include<iostream>
using namespace std;
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
vector<int>temp(nums1.begin(),nums1.begin()+ m);
int p1 = 0, p2 = 0, t = 0;
while (p2<n&&t<m)
{
if (nums2[p2] < temp[t]) {
nums1[p1++] = nums2[p2++];
}
else {
nums1[p1++] = temp[t++];
}
while(p2 == n && t<m) {
nums1[p1++]=temp[t++];
}
while (t==m && p2 < n) {
nums1[p1++]=nums2[p2++];
}
}
if (m == 0) {
nums1 = nums2;
}
if (n == 0) {
nums1 = nums1;
}
}
};
Solution s;
int main() {
vector<int>nums1;
vector<int>nums2 = {1 };
int m = 0, n = 1;
s.merge(nums1, m, nums2, n);
for (int i = 0; i < nums1.size(); i++)
{
cout << nums1[i];
}
}
我的思想
使用vector新建一个数组,将nums1中的有效元素赋值到temp数组中.
共由三种情况:
- nums1和nums2都不为空.
判断nums2和temp中的元素哪个小,将较小的数放到nums1中 - nums1为空
那么最终的nums1等价于nums2 - nums2为空
-那么最终的nums1还是原来的nums1
官方题解:
官方题解没有C++版本,但是有三种思想:
-
两个数组合并后再排序
-
因为最终得到的结果为nums1原数组, 所以先将原来的数组复制一份.从头开始遍历(我用的就是这种思想)
-
!!!(划重点啦)!!!
从数组后面开始遍历,不用使用新的数组空间.不用担心从从后面赋值过来会将nums1的有效元素覆盖,因为nums1的长度至少是m+n的.
我的代码优化:提交
//使用的官方题解三的思想
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p1 = m - 1, p2 = n - 1, p = n + m - 1;
while (p2 > -1)
{
if (p1 == -1) {
while (p2>-1)
{
nums1[p--] = nums2[p2--];
}
break;
}
if (nums2[p2] >= nums1[p1]) {
nums1[p--] = nums2[p2--];
}
else
{
nums1[p--] = nums1[p1];
nums1[p1] = -10000;
p1--;
}
}
}
};
我的代码优化:测试
#include<vector>
#include<iostream>
using namespace std;
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p1 = m - 1, p2 = n - 1, p = n + m - 1;
while (p2 > -1)
{
if (p1 == -1) {
while (p2>-1)
{
nums1[p--] = nums2[p2--];
}
break;
}
if (nums2[p2] >= nums1[p1]) {
nums1[p--] = nums2[p2--];
}
else
{
nums1[p--] = nums1[p1];
nums1[p1] = -10000;
p1--;
}
}
}
};
Solution s;
int main() {
vector<int>nums1 = { 4,5,6,0,0,0 };
vector<int>nums2 = { 1,2,3 };
int m = 3, n = 3;
s.merge(nums1, m, nums2, n);
for (int i = 0; i < nums1.size(); i++)
{
cout << nums1[i];
}
}
我的疑惑
我的题解三没有另外开数组空间复杂度为O(1),题解二另外开了一个数组temp空间复杂度为O(m),为什么题解三的内存消耗比内存二的内存消耗还大?求大佬解释解释,谢谢啦!
我学会了
1.边界处理的时候一定要小心小心再小心。注意数组越界
2.学会使用逆向思维,就比如此题的从后往前遍历就不用新开数组了,这样理论上就可以节省内存空间了.(实际运行结果求解求解求解)
3.C++使用vector数组简直不能再爽,这里推荐一篇文章:C++_vector操作
有不对或是可以改进的地方,有劳大佬指点指点!十分感谢呀