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
您确定没有从任何数组中丢失任何值吗?我怀疑你的代码会丢失一些索引。