Java 如何将一个大小为M的数组合并到另一个大小为2M的数组中
我在一次在线代码挑战中得到了这个问题。我需要将两个排序的数组合并,一个大小为Java 如何将一个大小为M的数组合并到另一个大小为2M的数组中,java,arrays,algorithm,big-o,mergesort,Java,Arrays,Algorithm,Big O,Mergesort,我在一次在线代码挑战中得到了这个问题。我需要将两个排序的数组合并,一个大小为M的M元素,另一个大小为M元素,容量为2M。我提供了以下解决方案: class ArraysSorting { /** * Function to move elements at the end of array * * @param bigger array */ void moveToEnd(int bigger[]) { int i = 0, j = bigger.length - 1;
M
的M
元素,另一个大小为M
元素,容量为2M
。我提供了以下解决方案:
class ArraysSorting {
/**
* Function to move elements at the end of array
*
* @param bigger array
*/
void moveToEnd(int bigger[]) {
int i = 0, j = bigger.length - 1;
for (i = bigger.length - 1; i >= 0; i--)
if (bigger[i] != 0) {
bigger[j] = bigger[i];
j--;
}
}
/**
* Merges array smaller array of size M into bigger array of size 2M
* @param bigger array
* @param smaller array
*/
void merge(int bigger[], int smaller[]) {
moveToEnd(bigger);
int i = smaller.length;
int j = 0;
int k = 0;
while (k < (bigger.length)) {
if ((i < (bigger.length) && bigger[i] <= smaller[j]) || (j == smaller.length)) {
bigger[k] = bigger[i];
k++;
i++;
} else {
bigger[k] = smaller[j];
k++;
j++;
}
}
}
}
类数组排序{
/**
*函数移动数组末尾的元素
*
*@param更大的数组
*/
void moveToEnd(整数大于[]){
int i=0,j=更大。长度-1;
对于(i=biger.length-1;i>=0;i--)
如果(大于[i]!=0){
更大的[j]=更大的[i];
j--;
}
}
/**
*将大小为M的较小阵列合并为大小为2M的较大阵列
*@param更大的数组
*@param较小的数组
*/
无效合并(整数较大[],整数较小[]){
移动到末端(更大);
int i=较小的长度;
int j=0;
int k=0;
而(k<(更大的长度)){
如果((i<(biger.length)&&biger[i]你不能超过线性时间,因为你必须至少扫描所有2M
元素,所以这是你能得到的最好结果
但实际上,您可以进一步优化它。无需将biger
的元素移到最后;只需将结果从右向左而不是从左向右写入即可(当然,您需要反转比较,在任何步骤中,您都需要选择最大的元素而不是最小的元素)
此外,这也不好:
if ((i < (bigger.length) && bigger[i] <= smaller[j]) || (j == smaller.length)) {
/* ... */
}
总的来说,我认为您可以使代码更简单,在我看来,这里有一些东西更容易阅读,因为if
条件更小,更容易理解(它也接近于合并两个数组的传统方式,避免了额外的O(M)
将元素移到后面的工作):
很容易看出,只要可以比较不同数组中的两个元素,第一个循环就会运行(而不是让循环始终运行并在内部使用复杂的if
测试)。还要注意的是,由于输出正在写入biger
,因此一旦第一个循环终止,我们只需确保其余的(如果有)剩下的较小的
被复制到较大的
。代码是C语言,但在Java中几乎相同。较大的
和较小的
是较大的
和较小的
中的元素数;假设较大的
有足够的空间容纳较大的
较小的
r_len元素。分配给较小的
和较大的
的初始if
测试对于处理边缘情况是必要的,在这种情况下,减去1将溢出大小
的(无符号)范围;在Java中,它们是不必要的,因为Java没有无符号类型(如果我错了,请纠正我,我最近没有使用Java)
时间复杂度仍然保持
O(M)
是的,Java中没有无符号类型,可以使用long而不是int:)
if ((j == smaller.length) || (i < (bigger.length) && bigger[i] <= smaller[j])) {
/* ... */
}
void merge(int bigger[], size_t bigger_len, int smaller[], size_t smaller_len) {
ssize_t smaller_i, bigger_i, idx;
if (smaller_len == 0)
return;
smaller_i = smaller_len-1;
if (bigger_len == 0)
bigger_i = -1;
else
bigger_i = bigger_len-1;
idx = bigger_len+smaller_len-1;
while (smaller_i >= 0 && bigger_i >= 0) {
if (bigger[bigger_i] > smaller[smaller_i]) {
bigger[idx] = bigger[bigger_i];
bigger_i--;
}
else {
bigger[idx] = smaller[smaller_i];
smaller_i--;
}
idx--;
}
while (smaller_i >= 0) {
bigger[idx] = smaller[smaller_i];
smaller_i--;
idx--;
}
}