是否有针对跳跃二进制搜索的直观解释
Is there an intuitive explanation for the jumping binary search?
我正在阅读竞争性程序员的手册: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
(。
不变的假设是:
- 词典中的单词以非删除顺序(对于每个
i
,0&lt;i
&lt;n
:array[i-1]
&lt; =array[i]
(, - 您当前在上查找的单词(
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)
的所有可能值(。然后,您以array
与array[k+b] <= x
相同的方式进行二进制搜索。
请注意,该书假设ok(i)
和f(i)
适用于任何i
,而阵列大小有限,必须检查:k+b < n
,其中n
是数组大小。
请注意书中的代码样式:
在竞争性编程中,您的时间非常有限,可以解决大量算法问题,再也不会查看代码,可以使用简短的变量名称,无评论等。许多#DEFINE
指令 - 参见例如https://gist.github.com/kodekracker/e09f9d23573f117a5db0。
我了解这可能是如何令人惊讶的。在长期专业项目的世界中,实施速度的交易代码可读性是不可接受的。
- 有根的二进制搜索树.保留与其父级的链接
- 在C++中搜索嵌套多映射值
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 二进制搜索树叶数问题
- 为什么二进制搜索在我的测试中不起作用
- 正在尝试重载二进制搜索树分配运算符
- c++binary_search函数排序数组(流行名称搜索)出现问题
- 向量上的线性搜索
- 如何在动态数组上使用搜索函数
- 对于MacOS上的G++,如何添加默认的include目录/usr/local/include和默认的库搜索路径/usr
- cmake:添加要搜索头文件的目录
- 使用C++创建特殊的二叉搜索树
- 在C++的字符串中搜索和删除某些字符
- std::unordered_map 搜索算法是如何实现的?
- 使用不变量来确定二分搜索中的边界条件
- 二叉搜索如何比线性搜索更快?
- 按边长度递归搜索图中所有可行路径
- QStackWidget - 按名称搜索
- 在递归二叉搜索树中搜索
- 是否有针对跳跃二进制搜索的直观解释