给定n个整数A [0 ... n-1]的数组,使得∀i,0≤i≤n,我们得到| A [i] -A [i + 1] |≤1,如果A [0] = x,A [n-1] = y,我们得到x
我不明白这个问题。我被困4天了。知道怎么用递归方式进行二分搜索,指数搜索或插值搜索?我们给出一个元素z找到索引j使得a [j] = z(a j)我是对的吗?
答案 0 :(得分:3)
此:
| A [i] -A [i + 1] | ≤1
表示数组中的每个元素最多 一个(-ve或+ ve)。然后,可以包含 z 的最接近的索引距离当前|A[cur] - z|
个空格。
所以,你所做的是从j=0
开始,并为每一步找出答案。跳过那么多空格,再次检查。最终你会找到z或到达终点。
public static int findZ(int[] a, int z){
int j = 0;
while(j < a.length){
if(a[j] == z)
return j
j += Math.abs(a[j] - z);
}
return -1;
}
这不是二进制或指数搜索,它不是递归的,但它很简单,可以完成工作。它用作单侧插值搜索。请参阅下面的双向方法。你可以将它变成一个递归函数,但这应该是直截了当的,我会把它留给你。
它在O(n)中运行,你的最坏情况表现将是{0,0,0,0,1}
,它只能跳一步,然后变成直线搜索。
最佳案例将被订购,像{0,1,2,3,4,5}
这样的独特成员,只会执行一次跳转。
为了使这更像“插值搜索”,让我们同时移动上限和下限。同样的逻辑适用于两端:
public static int findZ(int[] a, int z){
int j = 0;
int k = a.length - 1;
while(j <= k){
if(a[j] == z)
return j
if(a[k] == z)
return k;
j += Math.abs(a[j] - z);
k -= Math.abs(a[k] - z);
}
return -1;
}
它仍然以O(n)总体上更糟糕的情况结束,但是this is normal for an interpolation search。
现在最糟糕的情况更像是{0,0,0,1,0,0,0}
,而你最好的情况就像{0,1,2,3,2,1,0}
。