【问题标题】:Reduction of search space in binary search减少二分搜索中的搜索空间
【发布时间】:2021-08-23 12:57:29
【问题描述】:

我正在解决classical binary search problem

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty()) return -1;

        int lo=0, hi=nums.size()-1;
        while(lo<hi) {
            int mid=lo+(hi-lo)/2;
            //if element found at position mid, return mid
            if(nums[mid]==target) return mid;
            if(nums[mid]<target) lo=mid+1;
            //why not hi=mid-1, since if mid _could_ have our answer, we would 
            //have already returned above
            else hi=mid;
        }
        
        // if element not found, return -1;
        return nums[lo]==target ? lo : -1;
    }
};

我正在寻找设置hi=mid 的直观解释(特别是while 循环条件为lo&lt;hi 而不是lo&lt;=hi)。我认为我们应该将其设置为hi=mid-1,因为我们知道mid 不能包含我们的答案(如果包含,那么我们已经返回)。是的,我可以在几个示例上进行尝试,但我试图直观地了解在开发逻辑(在开始编码之前)时搜索空间是如何减少的,​​以便我可以想出一个具体的适用于所有示例的算法。

【问题讨论】:

  • 如果nums 为空,那你的问题就很大了。
  • @PaulMcKenzie,是的,是的。我已经编辑了代码。感谢您指出了这一点! :)
  • 再看你写的。设置hi=midlo&lt;hi 描述您不了解的当前情况,设置hi=mid-1lo&lt;=hi 描述您认为会更好的情况。你能想出一个案例,这些情况有不同的功能吗?
  • @JaMiT,你的意思是当lo==hi
  • @Someone 好的,我应该要求一个案例加上解释功能的不同之处。 lo==hi在这两种情况下会发生什么?

标签: c++ algorithm binary-search


【解决方案1】:

我正在寻找设置 hi=mid 的直观解释(特别是将 while 循环条件设置为 lo&lt;hi 而不是 lo&lt;=hi)。我认为我们应该将其设置为hi=mid-1,因为我们知道mid 不能包含我们的答案(如果包含,那么我们已经返回)。

这里有两个主要的潜在问题:

  1. 正确性。对于所有输入,函数是否终止并返回正确答案?

    • hi=mid,是的。为此,我们可以观察到当循环条件lo&lt;hi 成立时,mid 总是严格小于hi 但不小于lo,因此设置mid=hi 会减少搜索间隔。我们还可以观察到,当执行该替代方案时,如果目标值存在的话,它必须在缩小的区间内。由于搜索空间是有限的,并且在每次迭代中都会减少,因此如果没有尽快找到目标,计算最终必须达到间隔大小 1(并因此终止)。

    • hi=mid-1,也可以。论点是相同的,但值得注意的是,mid == lo 可能是这种情况,这产生了hi 设置小于lo 的可能性。写函数的时候不存在实际问题,但是有点不整洁。

  2. 效率。该函数能否以更少的步骤得出正确的结果?

    使用hi=mid-1 不会使函数渐近更快。无论哪种方式,它都是 O(log n)。此外,在任何给定的问题上,这两个备选方案将测试不同的值序列,因此当目标值存在时,任一备选方案可能会在比另一个备选方案更少的周期内完成。直觉表明,平均而言,将搜索间隔缩小一点将是一个轻微的胜利,尤其是在目标值不存在的情况下,但除了间隔已经非常小的周期外,这种增益在比例上是微不足道的。

我试图直观地了解在开发逻辑时(在开始编码之前)搜索空间是如何减少的,​​以便我可以提出一个适用于所有示例的具体算法。

任何一种替代方案都有效,没有理由期待明显的速度差异。那么,它归结为风格和个人敏感性。我自己,在这种情况下我更喜欢hi=mid,以避免产生hi &lt; lo的情况。其他人可能更喜欢 hi=mid-1 对称性。


旁注:另一方面,不能从 lo=mid+1 更改为 lo=mid。因为mid=lo+(hi-lo)/2 有可能导致mid==lo,所以需要lo=mid+1 替代方案来确保间隔在每个周期都缩小。

【讨论】:

  • 感谢您的解释。没有遵循旁注。你是指lo=mid+1lo=mid 吗?
  • 是的,@Someone,你是对的。我不小心在那里执行了变量交换,现在我已经修复了。
猜你喜欢
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2019-01-09
  • 1970-01-01
  • 2016-08-08
相关资源
最近更新 更多