合并排序的数组
题目
面试题 10.01. 合并排序的数组
给定两个排序后的数组 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]
解法一
解题思路
由于合并数组的空余位置在数组后半部分,所以如果从头开始进行比较合并会有多余的移动元素的操作;所以可以考虑从后往前遍历合并。
具体实现
定义三个index,分别对应A、B、新A数组的当前位置。比较A[i]和B[j]的值,将大值赋予数组末尾。操作完成后,倘若B数组未能遍历完,需要将剩余元素添加进去。
代码
class Solution {
public void merge(int[] A, int m, int[] B, int n) {
int i=m-1,j=n-1,cur=m+n-1;
while(i>=0&&j>=0) {
if(A[i]>=B[j]) {
A[cur]=A[i];
cur--;i--;
}
else {
A[cur]=B[j];
cur--;j--;
}
}
while(j>=0) {
A[cur]=B[j];
cur--;j--;
}//i就不用判断了,因为如果是i未能遍历完,他原位置就有序
}
}
解法二
解题思路
遍历数组B,将元素插入到A数组中;
具体实现
先对A中有效的m个数进行与B中元素的比较,如果A[i]>=B[j],就把元素B[j]插入到数组A中。如果结束时B中的数并未全部添加完,就需要将剩下的也全部放在A数组后边。
代码
class Solution {
public void merge(int[] A, int m, int[] B, int n) {
int i=0,j=0;
int count=0;
for(;i<(m+count)&&j<n;) {
if(A[i]>=B[j])//往A中添加B[i]
{
for(int k=count+m;k>i;k--) {
A[k]=A[k-1];//数组元素后挪
}
A[i]=B[j];
count++;//已添加元素个数
i++;
j++;
}
else {//else不可少,否则会越界
if(A[i]<B[j]) {
i++;
}}
}
for(;count<n;count++) {
A[m+count]=B[count];
}
}
}