给出2个不同长度的未排序数组A和Q。对于Q中的每个元素,在A中找到差异最小的元素。
int[] findSmallestDifference(int A[], int Q[]){
int []result = new int[Q.length];
// insert code to find difference for each Q
return result;
}
我在一次采访中遇到了这个问题,我提供了一些解决方案,但有人提到这还不是最佳选择。
我提供的解决方案:
我没想到的最佳解决方案是什么?
答案 0 :(得分:0)
以下方法可能更快,具体取决于数组中的数据。 但是可以说您有以下两个数组。
A = {1,2,5,11,13} and Q = {3,5,12}
创建两个新数组并填充该数组,以使旧数组中的值是新数组中的索引。因此,新数组的大小是旧数组中最大的数字,重复值将被忽略。例如:
它应该如何工作的示例(伪代码):
A'=null
Q'=null
A' and Q' have the size of the largest number in A or Q
for i < length(A) i++ {
A'[A[i]]=A[i]
B'[B[i]]=B[i]
}
A'= {1,2,null,null,5,null,....,null,11,null,13}
Q'= {null,null,3,null,5,null,....,12,null}
for i < length(A') i++ {
if(A[i] == Q[i]){
print(A[i])
} else if (A[i] == null) {
for(j=1 j < length(A') j++) {
if(Q[i+j] != null || Q[i-j] != null){ //here you have to be carfull nto go to -negative indices
print[Q[i-j],Q[i+j],A[i]]
Break;
}
}
}
}
然后比较两个数组的值以查看值的索引是否已填充。如果未填充,则查找下一个已填充的索引。
此方法的速度取决于稀疏分配两个数组的数目。如果您有非常大的数字(并且相距很远),那么这可能不是最佳选择。
该算法的最佳情况是O(A + Q),最坏情况是O(infinite)。
答案 1 :(得分:0)
对于| Q |的情况,我有一个构想。 <| A |基于Quickselect。想法是对A进行部分排序,同时通过搜索A差异最小的元素来连续处理Q中的元素。
因此,对于Q中的第一个元素,您需要执行类似于搜索的快速选择,以找到差异最小的元素。此搜索将花费O(A),但会对Q中的元素进行部分排序。Q中的第二个元素将已经从第一次搜索中获利,并进一步对A进行排序。
我目前不确定如何计算运行时复杂度,但是它可能比O(A log A)更好,因为在处理完Q中的所有元素之后不一定会对A进行完全排序。在最佳情况下,它可以是O(Q log A)。
不确定是否有帮助,但是也许有人可以找出缺失的部分。
答案 2 :(得分:0)
面试的重点可能是细节。 A和Q具有不同的长度。
因此,如果A将具有16个元素,而Q具有1个元素,则解决方案2可能不是最优的。
最佳解决方案是使用良好的排序算法(例如合并排序)对较小数组进行排序,该算法的最坏情况下的复杂度为O(NlogN)
,然后扫描更大的数组数组,并通过二进制排序在较小数组中找到最接近的元素。
您的解决方案2看起来是最优的,但是应该改写。