是否有针对跳跃二进制搜索的直观解释

Is there an intuitive explanation for the jumping binary search?

本文关键字:搜索 直观 解释 二进制 跳跃 是否      更新时间:2023-10-16

我正在阅读竞争性程序员的手册:https://cses.fi/book/book/book.pdf

在第32页及以上(PDF pp 42(上,提到了用于二进制搜索的方法2,我不确定我完全理解。然后,他们将其稍微修改以找到最小值,以使函数OK((为true,并尝试在数组中找到最大值。我不直观地了解这里发生了什么。有任何直观的解释吗?

int k = 0;
for (int b = n/2; b >= 1; b /= 2) {
    while (k+b < n && array[k+b] <= x) k += b;
}
if (array[k] == x) {
    // x found at index k
}

找到适用于功能的最小值

int x = -1;
for (int b = z; b >= 1; b /= 2) {
    while (!ok(x+b)) x += b;
}
int k = x+1;

找到首先增加然后降低

的函数的最大值
int x = -1;
for (int b = z; b >= 1; b /= 2) {
    while (f(x+b) < f(x+b+1)) x += b;
}
int k = x+1;

书中的解释非常好!我将使用它们作为起点。

想象您有一个字典,在第一页(int k = 0;(上打开它,然后在字典中寻找一个单词(x(。

不变的假设是:

  1. 词典中的单词以非删除顺序(对于每个 i,0&lt; i&lt; narray[i-1]&lt; = array[i](,
  2. 您当前在上查找的单词(array[k](永远不超过您在寻找的单词( array[k]&lt; = x始终是正确的(。

b是您距离答案有多少页的猜测。在二进制搜索中,您总是猜测最大距离的一半。最初,最大的距离是字典n的长度。因此,最初,您将字典长度的一半作为您的猜测-int b = n/2;

您将当前位置k移动到猜测的第2页b的数量,即只要满足假设2。然后您再次猜测,将猜测的距离b减半。

b变为1时,您在一直在寻找的字典中找到了页面。array[k] == x-字典包含页面k上的单词,或者您的字典中没有这样的单词。


!ok(x+b)f(x+b) < f(x+b+1)的后一个示例本质上与array[k+b] <= x的示例相同。

想象一下,您有一个数组,其中array[i]中的所有可能值!ok(i)(或array[i]f(i) < f(i+1)的所有可能值(。然后,您以arrayarray[k+b] <= x相同的方式进行二进制搜索。

请注意,该书假设ok(i)f(i)适用于任何i,而阵列大小有限,必须检查:k+b < n,其中n是数组大小。


请注意书中的代码样式:

在竞争性编程中,您的时间非常有限,可以解决大量算法问题,再也不会查看代码,可以使用简短的变量名称,无评论等。许多#DEFINE指令 - 参见例如https://gist.github.com/kodekracker/e09f9d23573f117a5db0。

我了解这可能是如何令人惊讶的。在长期专业项目的世界中,实施速度的交易代码可读性是不可接受的。