【问题标题】:Binary Search algorithm implementations二分搜索算法实现
【发布时间】:2017-01-06 08:57:33
【问题描述】:

我遇到了多个使用二分搜索变体来获得最终答案的问题。这些问题包括求数的平方根的下限、检查数是否是完全平方、求旋转数组中的最小值、求数组中数的第一个索引等。

所有算法都包含适当修改的低、高和中变量。

我在网上阅读了这些算法的几种变体,这些算法中总是有很大的机会出现一个错误,导致它错过了极端情况。对于以下变体,是否有任何标准可以帮助我了解何时应该使用哪一个?

1.变量的初始化

选项1:低= 0,高= arr.length

选项 2:低 = 0,高 = arr.length - 1

选项1:low = 1,high = arr.length

2。循环条件

选项1:while(low

选项2:同时(低

3。中间变量计算

选项1:中=(低+高)/2;

选项2:中=低+(高-低)/2;

4.条件检查和更新到低和高

选项 1:低 = 中,高 = 中

选项 2:低 = 中 AND 高 = 中 - 1

选项 3:低 = 中 + 1 AND 高 = 中

选项 4:低 = 中 + 1 且高 = 中 - 1

编辑:假设是 3 状态输出。数组索引从 0 开始。

【问题讨论】:

  • 这些选项的几种组合将导致正确的算法。它还取决于数组索引是从 0 开始还是从 1 开始。

标签: arrays algorithm binary-search


【解决方案1】:

好吧,您可以通过多种方式使其发挥作用,但是:

1) 我使用low=0, high=arr.length。如果我要调用变量lowhigh,那么我总是想要low<=high,即使在搜索结束时也是如此。 arr.length==0的时候这个也比较容易思考

2)while (low<high)。这对应于(1)的答案。循环完成后,我喜欢low==high,所以我不必担心使用哪个。

3) 始终使用mid=low+(high-low)/2mid = low+((high-low)>>1)。当数组变得太长并给出否定结果时,另一个选项会溢出。

4) 这取决于您使用的比较类型(3 态与 2 态输出)以及其他答案。对于 2 状态比较和上述答案,您会得到 low=mid+1high=mid。这是理想的,因为很明显范围每次迭代都会变小——mid+1 > low 很明显,mid < high,因为low<high(这是循环条件)和(high-low)/2 向下舍入。

【讨论】:

    【解决方案2】:

    您提到的选择并不是更糟更好。通常它只取决于一个实现,例如如果你通过high=arr.length,那么你宁愿写while(low < high)而不是while(low <= high)

    事实上,其中一些差异可能有意义。如果我们考虑使用二进制搜索算法在数组 A 中找到您的 X 数,并且会有一些(不仅仅是一个)元素等于 X,那么您可以找到第一个或最后一个的索引 - 这取决于实现。

    【讨论】:

    • 是的,我同意你的看法。但是一般来说,为任何此类问题做出决定的最佳方法是什么,以避免遗漏极端情况?
    • 如果您没有被指定必须准确地找到 FIRST 或 LAST 索引或类似的东西 - 按照您的流程,按照您理解的方式自己编写 binsearch。如果您了解您的代码的作用 - 您将能够轻松地将其调整为特殊情况。
    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多