我在采访中被问到这个问题。有两个大小为N和M的排序数组,它们连接在一起,因此生成的数组不会被排序。在结果中,从0到N-1的数组元素来自第一个数组,而从N到M + N-1的元素来自第二个数组。
如何在此类数组中查找整数。两个数组都包含唯一元素,两个原始数组之间没有交集。时间复杂度应为O(log(N + M)),空间复杂度应为O(1)。
e.g。
数组1是[3,4,5] 数组2是[1,2] 结果数组是[3,4,5,1,2]
如何搜索此数组?
答案 0 :(得分:0)
让我们使用合并排序方法。
现在,跳到最后一步,这里我们有两个已排序的数组,它们将被连接成一个列表。
我们做什么,从一个元素开始,并根据我们插入到数组中的顺序检查另一个数组的元素。
以同样的方式,我们搜索查看这两个数组的元素。
答案 1 :(得分:0)
因为数组[0,N-1]
和[N,N+M-1]
已排序。您可以在此数组中使用binary search
,这会导致log(N)+log(M)
复杂性,空间复杂度为O(1)
。
答案 2 :(得分:0)
如果您知道N
和M
,那么很容易。首先在第一部分进行二进制搜索,然后在第二部分进行二进制搜索。时间复杂度为O(log(N))
+ (O(log(M)) <= O(log(N+M))
。
如果您不知道N
和M
,那么您需要查看每个元素,即您不能比线性时间更好。
答案 3 :(得分:0)
O(log(M)+ log(N))大于O(log(M + N)),但不超过两倍:
O(log(M + N))&lt; = O(log(M)+ log(N))&lt; = 2 * O(log(M + N))
答案 4 :(得分:0)
我可以想到这个最优解决方案,我猜时间复杂度是O(Nlog(M-N)),考虑到N&lt; M.
一旦找到加入点,我们将对剩余元素进行二元搜索 两个迭代器都没有触及的数组。
class cls
{
public int search(int merged[], int x)
{
int ret = -1, a = 0 , b = 0;
boolean arrn = false;
//a is forward and b is backward iterator
//looking for index where arrays are joined.
for(b = merged.length - 1;a < b ;a++,b--)
{
//compare values of iterator to K
if( merged[a] == x )
{
ret = a;
return ret;
}
if ( merged[b] == x )
{
ret = b;
return ret;
}
//if a is the point where first array ends then
//do binarysearch in remaining element of array which
//are not visited by both a and b. Since original arrays
// soreted. It is guaranteed that a+1 to b is also sorted.
//
if ( !( merged[a] < merged[a + 1] ) )
{
ret = Arrays.binarySearch(merged, a+1, b, x);
return ret;
}
if ( !( merged[b - 1] < merged[b] ) )
{
ret = Arrays.binarySearch(merged, a + 1, b - 1, x);
return ret;
}
}
return ret;
}
}