2 minutes
Week1018_algorithm
ARTS - Algorithm
补 11.5
88. 合并两个有序数组
题目
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 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]
分析
首先想出解决方案,再优化解决方案。
这个问题可以先合并数组,再对数组排序,于是就有了如下代码:
public static void merge(int[] nums1, int m, int[] nums2, int n) {
for (int i = m, j = 0; i < m + n; i++, j++) {
nums1[i] = nums2[j];
}
for (int i = 0; i < m + n; i++) {
for (int j = i + 1; j < m + n; j++) {
if (nums1[i] > nums1[j]) {
int tmp = nums1[i];
nums1[i] = nums1[j];
nums1[j] = tmp;
}
}
}
}
这种解法虽说能解决问题,但是肯定存在更好的解法,主要是没有利用上数组的有序特性。考虑另一种解法,遍历两个数组,从前往后,小的放前面,大的放后面,感觉也不太好,因为牵涉到数组整体后移的情况。
看了答案之后豁然开朗, 要点是从后往前填数据,因为从后往前填数据,数据的位置已经是确定的了,不会再移动,所以代码如下
代码
public static void merge3(int[] nums1, int m, int[] nums2, int n) {
int ia = m - 1;
int ib = n - 1;
for (int i = m + n - 1; i >= 0 ; i--) {
if (ia >= 0 && ib < 0) {
break;
}
if (ia < 0 && ib >= 0) {
nums1[i] = nums2[ib--];
continue;
}
if (nums1[ia] > nums2[ib]) {
nums1[i] = nums1[ia--];
} else {
nums1[i] = nums2[ib--];
}
}
}
Read other posts