题目描述
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]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
合并后排序
时间复杂度 : O((n + m)\log(n + m))O((n+m)log(n+m))。
空间复杂度 : O(1)O(1)
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
/// Sorting
/// Time Complexity: O(nlogn)
/// Space Complexity: O(1)
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
assert(nums1.size() == m + n && nums2.size() == n);
for(int i = 0; i < n ; i ++ )
nums1[m + i] = nums2[i];
sort(nums1.begin(), nums1.end());
}
};
void print_vec(const vector<int>& vec){
for(int e: vec)
cout << e << " ";
cout << endl;
}
int main() {
vector<int> nums1 = {1, 3, 5, 7};
int m = nums1.size();
vector<int> nums2 = {2, 4, 6};
int n = nums2.size();
for( int i = 0 ; i < nums2.size() ; i ++ )
nums1.push_back(0);
Solution().merge(nums1, m, nums2, n);
print_vec(nums1);
return 0;
}
思路二
双指针从前往后,需额外开辟空间存储nums1开头的元素。
时间复杂度 : O(n + m)O(n+m)。
空间复杂度 : O(m)O(m)
//JAVA实现
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// Make a copy of nums1.
int [] nums1_copy = new int[m];
System.arraycopy(nums1, 0, nums1_copy, 0, m);
// Two get pointers for nums1_copy and nums2.
int p1 = 0;
int p2 = 0;
// Set pointer for nums1
int p = 0;
// Compare elements from nums1_copy and nums2
// and add the smallest one into nums1.
while ((p1 < m) && (p2 < n))
nums1[p++] = (nums1_copy[p1] < nums2[p2]) ? nums1_copy[p1++] : nums2[p2++];
// if there are still elements to add
if (p1 < m)
System.arraycopy(nums1_copy, p1, nums1, p1 + p2, m + n - p1 - p2);
if (p2 < n)
System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - p1 - p2);
}
}
思路三
双指针从后往前,无需开辟新空间
时间复杂度 : O(n + m)O(n+m)。
空间复杂度 : O(1)O(1)。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n)
{
int i=m-1;
int j=n-1;
int index=nums1.size()-1;
while(i>=0 && j>=0)
{
if(nums1[i]>=nums2[j])
nums1[index--]=nums1[i--];
else
nums1[index--]=nums2[j--];
}
while(i>=0)
nums1[index--]=nums1[i--];
while(j>=0)
nums1[index--]=nums2[j--];
}
};
待学习
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
/// Standard merge process in merge sort
/// Time Complexity: O(n)
/// Space Complexity: O(1)
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
assert(nums1.size() == m + n && nums2.size() == n);
for(int i = n + m - 1 ; i >= n ; i -- )
nums1[i] = nums1[i - n];
int i = n; // pointer for nums1 [n, n+m)
int j = 0; // pointer for nums2 [0, n)
int k = 0; // pointer merged nums1 [0, n+m)
while( k < n + m ){
if( i >= n+m )
nums1[k++] = nums2[j++];
else if( j >= n )
nums1[k++] = nums1[i++];
else if( nums1[i] < nums2[j] )
nums1[k++] = nums1[i++];
else
nums1[k++] = nums2[j++];
}
}
};
void print_vec(const vector<int>& vec){
for(int e: vec)
cout << e << " ";
cout << endl;
}
int main() {
vector<int> nums1 = {1, 3, 5, 7};
int m = nums1.size();
vector<int> nums2 = {2, 4, 6};
int n = nums2.size();
for( int i = 0 ; i < nums2.size() ; i ++ )
nums1.push_back(0);
Solution().merge(nums1, m, nums2, n);
print_vec(nums1);
return 0;
}