这是我参与更文挑战的第2天,活动详情查看: 更文挑战
题目
方法一
因为nums1数组一定有足够的空间,所以通过遍历nums2数组元素动态add进去就可以。
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
for (int i = 0; i < n; i++) {
nums1[m + i] = nums2[i];
}
Arrays.sort(nums1);
}
}
这里有取巧的成分了,因为直接使用了Arrays.sort方法。感觉不是出题人的意图。
方法二
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p1 = 0;
int p2 = 0;
int[] result = new int[m + n];
int current;
while (p1 < m || p2 < n) {
//如果nums1已经取完了,那么直接取nums2的
if (p1 == m) {
current = nums2[p2];
p2++;
} else if (p2 == n) {//如果nums2已经取完了,那么直接取nums1的
current = nums1[p1];
p1++;
} else if (nums1[p1] < nums2[p2]) {//比较两个数的大小,然后进行指针的移动
current = nums1[p1];
p1++;
} else {
current = nums2[p2];
p2++;
}
result[p1 + p2 - 1] = current;
}
//重新赋值
for (int i = 0; i < result.length; i++) {
nums1[i] = result[i];
}
}
}
复杂度分析
- 时间复杂度:,
while中最多遍历m+n,加上for的m+n,所以最坏的情况下是2(m+n)等于 - 空间复杂度:,申请了一个
m+n的数组
方法三:逆向指针
从题目可以知道nums1的空间是足够大的,逆向指针的方法就是要除去方法二的临时数组申请,思路是从nums1和nums2
的数组末尾取数,比较其值,大的放nums1末尾,因为nums1的空间大于m+n,最坏的情况下,nums2里面的全部元素 都比nums1大,这样就不会存在覆盖原有nums1数据的问题。
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p1 = m - 1;
int p2 = n - 1;
int current;
while (p1 > -1 || p2 > -1) {
//如果nums1已经取完了,那么直接取nums2的
if (p1 == -1) {
current = nums2[p2];
p2--;
} else if (p2 == -1) { //如果nums2已经取完了,那么直接取nums1的
current = nums1[p1];
p1--;
} else if (nums1[p1] < nums2[p2]) {//比较两个数的大小,然后进行指针的移动
current = nums2[p2];
p2--;
} else {
current = nums1[p1];
p1--;
}
nums1[p1 + p2 + 2] = current;
}
}
}
复杂度分析
- 时间复杂度:,最多遍历
m+n次 - 空间复杂度:,原地排序,常数额外空间