(1)题目描述
LeetCode链接:合并两个有序数组
(2)解题思路
1)思路1:合并后排序
将数组 nums2 放到数组 nums1 的尾部,
然后用 qsort 函数对整个数组进行排序。
- 时间复杂度:O((m+n)log(m+n)),qsort 函数快速排序的时间复杂度为nlogn
- 空间复杂度:O(1)
2)思路2:归并到新数组
开辟一个长度为 m+n 的新数组,
设置两个指针 p1 和 p2 从前往后遍历数组 nums1 和 nums2 ,初始分别指向 nums1 和 nums2 的头部,
每次比较 p1 和 p2 指向位置的数值,取出较小的从前往后依次放到新数组中。
再将新数组中的元素依次拷贝到 nums1 中
- 时间复杂度:O(m+n)
- 空间复杂度:O(m+n)
3)思路3:逆向双指针
从后面开始确定,从后向前遍历数组,
设置指针 p1 和 p2 分别指向 nums1 和 nums2 的有效数字的尾部,从尾部向前一边比较一边遍历,再设置指针 dst 指向 nums1 的尾部,
每次比较完 p1 和 p2 指向位置的数值大小后,通过 dst 从后往前填充,每次取两者之中的较大者放到 nums1 的最后面。
- 时间复杂度:O(m+n)
- 空间复杂度:O(1)
因为两个数组长度不一样,数据不一样,不知道哪一个指针先结束,还需要考虑到这两种情况:
(1)nums1 的指针 p1 先遍历完,指针 p2 还没有遍历完,此时还需要把 nums2 的数据挪过去
(2)nums2 的指针 p2 先遍历完,就不用处理了,因为剩下的数本来就在nums1里面
代码如下:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
//p1和p2分别指向数组nums1和nums2的有效数字的尾部
int p1 = m - 1;
int p2 = n - 1;
//dst指向数组nums1的尾部
int dst = m + n - 1;
//从后往前依次比较p1和p2指向位置的元素的大小
while(p1 >= 0 && p2 >= 0) //p1和p2有一个遍历完,则结束循环
{
if(nums1[p1] >= nums2[p2])
{
nums1[dst--] = nums1[p1--];
}
else if(nums1[p1] < nums2[p2])
{
nums1[dst--] = nums2[p2--];
}
}
//如果是p2先遍历完,就不用处理,因为剩下的数本来就在nums1里面
//如果p1先遍历完,p2还没有遍历完,则需要把nums2的数据挪过去
while(p1 < 0 && p2 >=0)
{
nums1[dst--] = nums2[p2--];
}
}
大家快去动手练习一下吧!