Java 合并两个排序的数组时,使用数组还是队列更好?

Java 合并两个排序的数组时,使用数组还是队列更好?,java,arrays,algorithm,queue,mergesort,Java,Arrays,Algorithm,Queue,Mergesort,我在一个编程实践网站上工作,该网站要求实现一个合并两个排序数组的方法。这是我的解决方案: public static int[] merge(int[] arrLeft, int[] arrRight){ int[] merged = new int[arrRight.length + arrLeft.length]; Queue<Integer> leftQueue = new LinkedList<>(); Queue<Intege

我在一个编程实践网站上工作,该网站要求实现一个合并两个排序数组的方法。这是我的解决方案:

  public static int[] merge(int[] arrLeft, int[] arrRight){
    int[] merged = new int[arrRight.length + arrLeft.length];

    Queue<Integer> leftQueue = new LinkedList<>();
    Queue<Integer> rightQueue = new LinkedList<>();

    for(int i = 0; i < arrLeft.length ; i ++){
        leftQueue.add(arrLeft[i]);
    }

    for(int i = 0; i < arrRight.length; i ++){
        rightQueue.add(arrRight[i]);
    }

    int index = 0;
    while (!leftQueue.isEmpty() || !rightQueue.isEmpty()){

        int largerLeft = leftQueue.isEmpty() ? Integer.MAX_VALUE : leftQueue.peek();
        int largerRight = rightQueue.isEmpty() ? Integer.MAX_VALUE : rightQueue.peek();

        if(largerLeft > largerRight){
            merged[index] = largerRight;
            rightQueue.poll();
        } else{
            merged[index] = largerLeft;
            leftQueue.poll();
        }

        index ++;
    }
    return merged;
   }
public static int[] merge(int[] arrLeft, int[] arrRight){
    // Grab the lengths of the left and right arrays
    int lenLeft = arrLeft.length;
    int lenRight = arrRight.length;
    // Create a new output array with the size = sum of the lengths of left and right
    // arrays
    int[] arrMerged = new int[lenLeft+lenRight];
    // Maintain 3 indices, one for the left array, one for the right and one for 
    // the merged array
    int indLeft = 0, indRight = 0, indMerged = 0;
    // While neither array is empty, run a while loop to merge
    // the smaller of the two elements, starting at the leftmost position of 
    // both arrays
    while(indLeft < lenLeft && indRight < lenRight){
        if(arrLeft[indLeft] < arrRight[indRight])
            arrMerged[indMerged++] = arrLeft[indLeft++];
        else
            arrMerged[indMerged++] = arrRight[indRight++];
    }
    // Another while loop for when the left array still has elements left
    while(indLeft < lenLeft){
        arrMerged[indMerged++] = arrLeft[indLeft++];
    }
    // Another while loop for when the right array still has elements left
    while(indRight < lenRight){
        arrMerged[indMerged++] = arrRight[indRight++];
    }
    return arrMerged;
}
公共静态int[]合并(int[]左对齐,int[]右对齐){
int[]合并=新int[arrRight.length+arrlight.length];
Queue leftQueue=新建LinkedList();
Queue rightQueue=新建LinkedList();
for(int i=0;i大右){
合并[索引]=更大的权限;
rightQueue.poll();
}否则{
合并[索引]=大左;
leftQueue.poll();
}
索引++;
}
返回合并;
}
但这是官方的解决方案:

  public static int[] merge(int[] arrLeft, int[] arrRight){
    int[] merged = new int[arrRight.length + arrLeft.length];

    Queue<Integer> leftQueue = new LinkedList<>();
    Queue<Integer> rightQueue = new LinkedList<>();

    for(int i = 0; i < arrLeft.length ; i ++){
        leftQueue.add(arrLeft[i]);
    }

    for(int i = 0; i < arrRight.length; i ++){
        rightQueue.add(arrRight[i]);
    }

    int index = 0;
    while (!leftQueue.isEmpty() || !rightQueue.isEmpty()){

        int largerLeft = leftQueue.isEmpty() ? Integer.MAX_VALUE : leftQueue.peek();
        int largerRight = rightQueue.isEmpty() ? Integer.MAX_VALUE : rightQueue.peek();

        if(largerLeft > largerRight){
            merged[index] = largerRight;
            rightQueue.poll();
        } else{
            merged[index] = largerLeft;
            leftQueue.poll();
        }

        index ++;
    }
    return merged;
   }
public static int[] merge(int[] arrLeft, int[] arrRight){
    // Grab the lengths of the left and right arrays
    int lenLeft = arrLeft.length;
    int lenRight = arrRight.length;
    // Create a new output array with the size = sum of the lengths of left and right
    // arrays
    int[] arrMerged = new int[lenLeft+lenRight];
    // Maintain 3 indices, one for the left array, one for the right and one for 
    // the merged array
    int indLeft = 0, indRight = 0, indMerged = 0;
    // While neither array is empty, run a while loop to merge
    // the smaller of the two elements, starting at the leftmost position of 
    // both arrays
    while(indLeft < lenLeft && indRight < lenRight){
        if(arrLeft[indLeft] < arrRight[indRight])
            arrMerged[indMerged++] = arrLeft[indLeft++];
        else
            arrMerged[indMerged++] = arrRight[indRight++];
    }
    // Another while loop for when the left array still has elements left
    while(indLeft < lenLeft){
        arrMerged[indMerged++] = arrLeft[indLeft++];
    }
    // Another while loop for when the right array still has elements left
    while(indRight < lenRight){
        arrMerged[indMerged++] = arrRight[indRight++];
    }
    return arrMerged;
}
公共静态int[]合并(int[]左对齐,int[]右对齐){
//获取左右数组的长度
int lenLeft=arrlleft.length;
int lenRight=arrrright.length;
//创建一个新的输出数组,其大小=左侧和右侧的长度之和
//阵列
int[]arrMerged=新int[lenLeft+lenRight];
//保留3个索引,一个用于左数组,一个用于右数组,一个用于右数组
//合并数组
int indLeft=0,indRight=0,indMerged=0;
//当两个数组都不为空时,运行While循环进行合并
//两个元素中较小的一个,从
//两个阵列
while(indLeft

显然,网站上用户的所有其他解决方案也没有使用队列。我想知道使用队列是否效率较低?例如,我在面试中使用队列会受到处罚吗

由于问题已经说明左输入数组和右输入数组是排序的,这提示您应该能够解决问题,而不需要输出数组以外的数据结构

在真实的面试中,当你编写解决方案时,面试官很可能会要求你讲述你的思维过程。他们可能会声明,他们希望解决方案在某些约束条件下实现。在开始编码之前,确保问题已经定义好是非常重要的。在开始之前,尽可能多地提出问题,以尽可能地约束问题

当您完成解决方案的实施后,您可以提及实施的时间和空间复杂性,并建议一个替代的、更高效的解决方案

例如,在描述您的实现时,您可以谈论以下内容:

  • 创建队列时存在开销
  • 解决方案的大O表示法/时间和空间复杂性
  • 在进行任何合并之前,您不必要地对左输入数组和右输入数组的每个元素进行迭代,以创建队列
  • 等等

这类面试问题在申请谷歌、微软、亚马逊和一些科技初创公司的职位时很常见。为了准备这些问题,我建议你在书中解决问题,比如。这本书介绍了如何解决这些问题,以及这类公司的面试过程。

很抱歉,你的排队解决方案太糟糕了

您正在将所有元素复制到辅助动态数据结构(由于内存分配,这可能会非常昂贵),然后再复制回目标阵列

合并的一大“缺点”是它需要两倍的存储空间,因为它不能在适当的位置完成(或者至少没有直接的方式)。但是,不必要地增加额外的副本和开销,会在更大程度上破坏事情

真正的解决方案是直接从源代码复制到目标代码,从而生成更简单、更高效的代码

还请注意,当其中一个队列耗尽时,使用sentinel值(
Integer.MAX_value
)是一个错误的好主意,因为当您提前知道结果时,它会添加额外的比较。与参考代码中一样,最好分成三个循环


最后,当数据恰好包含
整数时,您的解决方案可能会失败。MAX_VALUE

您确定没有从任何数组中丢失任何值吗?我怀疑你的代码会丢失一些索引。