合并排序的数组
给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。
初始化 A 和 B 的元素数量分别为 m 和 n。
示例:
输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
暴力法
class Solution {
public void merge(int[] A, int m, int[] B, int n) {
int j = 0;
for(int i = m;i<m+n;i++){
A[i] = B[j++];
}
Arrays.sort(A);
}
}
双指针
在确定两个排序的数组后,一般的解题思路是,使用循环比较大小,然后在根据大小排序插入。
我们可以这样考虑,从数组的尾端开始,我们可以在一个数组的基础上分配两个数组的大小长度,然后逆序比较。
思路分为两步;
1.在逆序的过程中,我们可以首先确定最后的位置,我们比较A数组和B数组,如果A大于B,
那么将A的最后一个元素插入末尾,定位尾端的标志符向前推进,然后A向前推进,继续和B的尾端比较。
2.如果B的A的尾端,那么将B的最后一个元素插入末尾,定位尾端的标志符向前推进,
然后B向前推进,继续和A的尾端比较。
具体的实现代码如下:
class Solution {
public void merge(int[] A, int m, int[] B, int n) {
int p1 = m - 1, p2 = n - 1;
int tail = m + n - 1;
int cur;
while (p1 >= 0 || p2 >= 0) {
if (p1 == -1) {
cur = B[p2--];
} else if (p2 == -1) {
cur = A[p1--];
} else if (A[p1] > B[p2]) {
cur = A[p1--];
} else {
cur = B[p2--];
}
A[tail--] = cur;
}
}
}
Golang
直接合并后排序
func merge(nums1 []int, m int, nums2 []int, _ int) {
copy(nums1[m:], nums2)
sort.Ints(nums1)
}
逆向双指针
func merge(nums1 []int, m int, nums2 []int, n int) {
p1, p2, sum := m-1, n-1, m+n-1
for ; p1>=0 || p2>=0; sum-- {
cur := 0
if p1 == -1 {
cur = nums2[p2]
p2--
} else if p2 == -1 {
cur = nums1[p1]
p1--
} else if nums1[p1] > nums2[p2] {
cur = nums1[p1]
p1--
} else {
cur = nums2[p2]
p2--
}
nums1[sum] = cur
}
}