您的位置:首页 > 其它

Cracking the coding interview--Q9.1

2014-12-14 21:35 501 查看
原文:

You are given two sorted arrays, A and B, and A has a large enough buffer at the end to hold B. Write a method to merge B into A in sorted order.

译文:

A和B是两个有序数组(假设为递增序列),而且A的长度足以放下A和B中所有的元素, 写一个函数将数组B融入数组A,并使其有序。

最简单的方法是开一个大小可以容纳A和B的数组C,然后像归并排序中合并两个数组一样, 按照大小顺序把数组A和数组B的元素一一地放入数组C,然后再将数组C拷贝给A。 这种方法额外地使用了O(n)的空间,显然这是没有必要的开销。由于A的大小已经足够用了, 所以直接在A上直接操作即可。

可是如果我们思维定势地对比数组A和数组B,每次取小的元素放入数组A, 这样就会发现,要放入的位置上正放着有用的元素。处理起来就麻烦了。

相反,如果我们从A和B的尾部元素开始对比,每次取大的元素放在数组A的尾部, 这样一来,要放入的位置就不会出现上面的冲突问题。当对比结束时, 即可得到一个排好序的数组A。代码如下:

package chapter_9_SortingandSearching;

/**
*
* A和B是两个有序数组(假设为递增序列),而且A的长度足以放下A和B中所有的元素, 写一个函数将数组B融入数组A,并使其有序。
*
*/
public class Question_9_1 {
/**
* @param a
* @param b
*
* 开辟数据c暂存比较数据
* 时间复杂度为0(a + b)
* 空间复杂度0(a)
*
*/
public static void mergeArray(int a[], int b[]) {
int lena = a.length;
int lenb = b.length;

int c[] = new int[lena];
int i = 0, j =0, k = 0;
for(; a[i] != 0 && j < lenb;) {
if(a[i] <= b[j]) {
c[k++] = a[i++];
} else {
c[k++] = b[j++];
}
}

if(a[i] == 0) {
while(j != lenb) {
c[k++] = b[j++];
}
} else {
while(a[i] != 0) {
c[k++] = a[i++];
}
}

for(int h=0 ;h<lena; h++) {
a[h] = c[h];
}
}

/**
* @param a
* @param b
*
* 直接从尾部比较开始,则计算两个数组的长度,就可以得知尾部a存储位置
*
*/
public static void mergeArray2(int a[], int b[]) {
int len;
int i = a.length - 1;
int j = b.length - 1;
while(a[i] == 0) {
i --;
}
len = i + 1;
int k = len - 1 + j;

for(; i >= 0 && j >= 0;) {
if(a[i] >b[j]) {
a[k--] = a[i--];
} else {
a[k--] = b[j--];
}
}

while(j >= 0) {
a[k--] = b[j--];
}
}

public static void printArray(int a[]) {
for(int i=0; a[i]!=0; i++) {
System.out.print(" " + a[i]);
}
}

public static void main(String args[]) {
int a[] = new int[20];
for(int i=0; i<10; i++) {
a[i] = i*3+1;
}
int b[] = new int[]{2, 4, 15, 23};

mergeArray2(a, b);
printArray(a);
System.out.print("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法