Java 面试问题-在排序数组X中搜索索引i,使X[i]=i
在昨天的采访中,我被问到了以下问题:Java 面试问题-在排序数组X中搜索索引i,使X[i]=i,java,c++,arrays,algorithm,Java,C++,Arrays,Algorithm,在昨天的采访中,我被问到了以下问题: 考虑java或C++数组,如“代码> x ,排序后,两个元素中没有两个元素相同。如何才能最好地找到一个索引,比如说i,使该索引处的元素也是i。这就是X[i]=i 作为澄清,她还给了我一个例子: Array X : -3 -1 0 3 5 7 index : 0 1 2 3 4 5 Answer is 3 as X[3] = 3. 我能想到的最好的方法就是线性搜索。面试后,我对这个问题想了很多,但没有找到更好的解决办法。我的论点是:具有requir
考虑java或C++数组,如“代码> x <代码>,排序后,两个元素中没有两个元素相同。如何才能最好地找到一个索引,比如说
i
,使该索引处的元素也是i
。这就是X[i]=i
作为澄清,她还给了我一个例子:
Array X : -3 -1 0 3 5 7
index : 0 1 2 3 4 5
Answer is 3 as X[3] = 3.
我能想到的最好的方法就是线性搜索。面试后,我对这个问题想了很多,但没有找到更好的解决办法。我的论点是:具有required属性的元素可以位于数组中的任何位置。所以它也可能在数组的最末端,所以我们需要检查每个元素
我只是想从这里的社区确认我是对的。请告诉我我是对的:)有一些更快的解决方案,取O(对数n)的平均值,或者在某些情况下取O(对数n)而不是O(n)。在谷歌上搜索“二进制搜索”和“插值搜索”,你可能会找到很好的解释 如果数组是未排序的,那么是的,元素在任何地方,并且不能在O(n)之下,但排序数组不是这样 -- 根据要求对插值搜索进行一些解释: 虽然二进制搜索仅涉及按“较大/不较大”比较两个元素,但插值搜索也尝试使用数值。关键是:你有一个从0到20000的排序范围。你看300-二进制搜索将从范围的一半开始,在10000。插值搜索猜测300可能比20000更接近于0,因此它将首先检查元素6000,而不是10000。然后,如果它太高,则递归到较低的子范围,如果它太低,则递归到较高的子范围 对于具有+-均匀分布值的大数组,插值搜索应该比二进制搜索快得多-编写代码并亲自查看。此外,如果首先使用一个插值搜索步骤,然后使用一个二进制搜索步骤,依此类推,效果最好
请注意,这是人类在字典中查找内容时凭直觉所做的事情。您可以执行二进制搜索: 在中间搜索,如果值低于索引,则没有更低的索引将包含相同的值
然后搜索上半部分,继续搜索,直到找到元素,或到达一个元素范围。这可以在
O(logN)
时间和O(1)
空间中使用稍微修改的
考虑一个新数组Y
,使得Y[i]=X[i]-i
Array X : -3 -1 0 3 5 7
index : 0 1 2 3 4 5
Array Y : -3 -2 -2 0 1 2
由于X
中的元素的顺序是递增的,因此
新数组Y
将按非降序排列。所以一个二进制
在Y
中搜索0
将给出答案
但是创建Y
需要O(N)
空间和O(N)
时间。所以不是
创建新数组时,只需修改二进制搜索,使
对Y[i]
的引用替换为X[i]-i
算法:
function (array X)
low = 0
high = (num of elements in X) - 1
while(low <= high)
mid = (low + high) / 2
// change X[mid] to X[mid] - mid
if(X[mid] - mid == 0)
return mid
// change here too
else if(X[mid] - mid < 0)
low = mid + 1;
else
high = mid - 1;
end while
return -1 // no such index exists...return an invalid index.
end function
函数(数组X)
低=0
高=(X中的元素数)-1
虽然(低的顶部,我的头,做二进制分裂可能会更快
看看中间值,如果它很高,那么你需要什么,在下半部分重新搜索
经过一次比较后,您已经将数据集一分为二了我认为这会更快
从列表中间开始< /P>
如果X[i]>i,则转到剩余左侧的中间
如果X[i]
继续这样做,每个循环的可能元素数量将减少一半。阅读问题后,似乎有一种情况可用于加速查找。在将位置与值进行比较时,如果值大于位置,则该值可以用作下一个要评估的位置。这将有助于更快地跳转数组。这是可以做到的,因为数组已排序。从概念上讲,我们跳过的值在数组中向左移动,并且位于错误的位置
例如:
int ABC[] = { -2, -5, 4, 7, 11, 22, 55 };
如果我的当前位置为2,且其值为4,则它们不相等,从概念上讲,值4向左移动。我可以使用值4作为我的下一个位置,因为如果值4不正确,则小于4的所有内容也不正确
以下示例代码仅供讨论:
void main()
{
int X[] = { -3, -1, 0, 3, 5, 7};
int length = sizeof(X)/sizeof(X[0]);
for (int i = 0; i < length;) {
if (X[i] > i && X[i] < length)
i = X[i]; // Jump forward!
else if (X[i] == i) {
printf("found it %i", i);
break;
} else
++i;
}
}
void main()
{
int X[]={-3,-1,0,3,5,7};
int length=sizeof(X)/sizeof(X[0]);
对于(int i=0;ii&&X[i]
我想修改后的二进制搜索版本就足够了
假设序列是
Array : -1 1 4 5 6
Index : 0 1 2 3 4
Result : 1
或
从这两个示例中,我们可以看到,如果mid
mid <- (first + last )/2
if a[mid] == mid then
return mid
else if a[mid] < mid then
recursive call (a,mid+1,last)
else
recursive call (a,first,mid-1)
midJava:
公共静态布尔检查(int[]数组,int i)
{
if(i<0 | | i>=array.length)
返回false;
返回(数组[i]==i);
}
C++:
bool检查(int数组[],int数组大小,int i)
{
if(i<0 | | i>=数组大小)
返回false;
返回(数组[i]==i);
}
它不需要像@codaddict建议的那样考虑任何数组Y
使用二进制搜索并检查给定数组的中间元素,如果它低于其索引,则不需要检查任何较低的索引,因为数组是
如果我们向左移动,减去m个索引和(至少)m个
mid <- (first + last )/2
if a[mid] == mid then
return mid
else if a[mid] < mid then
recursive call (a,mid+1,last)
else
recursive call (a,first,mid-1)
public static boolean check (int [] array, int i)
{
if (i < 0 || i >= array.length)
return false;
return (array[i] == i);
}
bool check (int array[], int array_size, int i)
{
if (i < 0 || i >= array_size)
return false;
return (array[i] == i);
}
int function(int[] arr) {
int low = 0;
int high = arr.length - 1;
while(low <= high) {
int mid = high - (high - low) / 2;
if(arr[mid] == mid) {
return mid;
} else if(arr[mid] < mid) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1; // There is no such index
}
//invariant: startIndex <= i <= endIndex
int modifiedBsearch(int startIndex, int endIndex)
{
int sameValueIndex = -1;
int middleIndex = (startIndex + endIndex) /2;
int middleValue = array[middleIndex];
int endValue = array[endIndex];
int startValue = array[startIndex];
if(middleIndex == middleValue)
return middleValue;
else {
if(middleValue <= endIndex)
sameValueIndex = modifiedBsearch(middleIndex + 1, endIndex)
if(sameValueIndex == -1 && startValue <= middleIndex)
sameValueIndex = modifiedBsearch(startIndex, middleIndex -1);
}
return sameValueIndex;
}