合并两个有序数组
题目描述
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0 ,应忽略。nums2
的长度为 n 。
解题思路
- 这道题我的第一想法就是先合并,再进行排序,这种方式最容易想到,但是时间复杂度较高。
- 官方题解中有双指针法,时间复杂度为
O(n)
。
代码
先合并再排序
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// 全部合并到nums1中
for (int i = m; i < nums1.length; i++) {
nums1[i] = nums2[i - m];
}
// 使用插入排序
int index = 1;
while (index < nums1.length) {
for (int j = index; j > 0; j--) {
if (nums1[j] < nums1[j - 1]) {
int t = nums1[j];
nums1[j] = nums1[j - 1];
nums1[j - 1] = t;
} else {
break;
}
}
index++;
}
}
}
双指针
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// 构造结果数组
int[] res = new int[m + n];
int len = nums1.length;
// 定义两个数组的头指针
int ptr_nums1 = 0, ptr_nums2 = 0;
for (int i = 0; i < len; i++) {
// 当两个数组都没有遍历完时
if (ptr_nums1 < m && ptr_nums2 < n) {
if (nums1[ptr_nums1] < nums2[ptr_nums2]) {
res[i] = nums1[ptr_nums1];
ptr_nums1++;
} else {
res[i] = nums2[ptr_nums2];
ptr_nums2++;
}
} else {
// 找出还没有排完的,依次加入即可
if (ptr_nums1 < m) {
res[i] = nums1[ptr_nums1];
ptr_nums1++;
}
else {
res[i] = nums2[ptr_nums2];
ptr_nums2++;
}
}
}
// 最后赋值给nums1
for (int j = 0; j < len; j++) {
nums1[j] = res[j];
}
}
}