【LeetCode-数组】合并两个有序数组
题目描述
给你两个有序整数数组 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]
题目链接: https://leetcode-cn.com/problems/merge-sorted-array/
思路1
将 nums2 中的元素放到 nums1 的后面,然后对 nums1 排序。代码如下:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums1.empty() && nums2.empty()) return;
if(nums2.empty()) return;
for(int i=0; i<n; i++){
nums1[m+i] = nums2[i];
}
sort(nums1.begin(), nums1.end());
}
};
- 时间复杂度:(m+n)log(m+n)
对合并后数组排序的时间复杂度,m+n 为合并后 nums1 的长度。 - 空间复杂度:O(1)
思路2
使用 3 个指针:p1 指向 nums1 的第 m-1 个元素(从 0 开始计数)、p2 指向 nums2 的第 n-1 个元素(从 0 开始计数)、p3 指向 nums1 的最后一个元素,也就是第 m+n-1 个元素(从 0 开始计数)。从后往前将 nums2 中的元素插入到 nums1 中:
- 如果 p1<0,说明 nums1 已经全部插入到新的 nums1 了,将 nums2[p2] 插入到 nums1[p3], p2--, p3--;
- 如果 p2<0,说明 nums2 已经全部插入到新的 nums1 了,将 nums1[p1] 插入到 nums1[p3], p1--, p3--;
- 如果 nums1[p1]>nums2[p2],因为要保证合并后的数组有序,所以将 nums1[p1] 插入到 nums1[p3], p1--, p3--;
- 如果 nums1[p1]<=nums2[p2],因为要保证合并后的数组有序,将 nums2[p2] 插入到 nums1[p3], p2--, p3--;
从后往前合并避免了从前往后合并要移动元素的问题。代码如下:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums1.empty() && nums2.empty()) return;
if(nums2.empty()) return;
int p1 = m-1;
int p2 = n-1;
int p3 = m+n-1;
for(; p3>=0 && (p1>=0 || p2>=0); p3--){
if(p1 < 0){
nums1[p3] = nums2[p2];
p2--;
}else if(p2 < 0){
nums1[p3] = nums1[p1];
p1--;
}else if(nums1[p1] > nums2[p2]){
nums1[p3] = nums1[p1];
p1--;
}else if(nums1[p1] <= nums2[p2]){
nums1[p3] = nums2[p2];
p2--;
}
}
}
};
- 时间复杂度:O(m+n)
- 空间复杂度:O(1)