【问题标题】:invariant of binary search for finding first occurrence of an element用于查找第一次出现的元素的二进制搜索不变量
【发布时间】:2019-05-24 08:28:42
【问题描述】:

我在定义查找二进制搜索的第一个元素的不变量时遇到了问题。 (我有一个排序数组 a,我想找到第一个等于某个数字 q 的元素,如果它不存在则返回 -1)

首先,我暂时设置了这个不变量。

我的不变量

“总是 a[l] q” ==> “总是 l ind”。

根据我的不变量,我写了这段代码:

int l=0,r=n;
while(l<r){
    int mid=(r+l)/2;
    if(a[mid]==q){
        r=mid+1;
    }
    else{
        if(a[mid]>q){
            r=mid;
        }else if(a[mid]<q) l=mid+1;
    }
}
return l;

但是有一个问题是if(a[mid]==q) 然后我必须选择一个不违反我的不变量的r

如果我选择mid-1,我将违反它,因为a[r] 将是q。

而且我必须遍历我的索引,直到找到一个索引 I,即 a[i]&gt;q,然后将 r 设置为该索引。 (r=i)==>但如果我这样做就不是O(log n)

我已经看到一些代码实现了lower_bound,即if(a[mid]==q)r 设置为mid,但我认为它们违反了它们的不变性,但它们的代码是正确的并返回正确的值。

喜欢这段代码:

1- int l = 0;
2- int r = n; // Not n - 1
3- while (l < r) {
4-     int mid = (l + r) / 2;
5-     if (q <= a[mid]) {
6-         r = mid;
7-     } else {
8-         l = mid + 1;
9-     }
10- }
11- return l;

首先,不变量就像我的不变量(i[l,r) 的范围内)但在第 5 行考虑 if(q==a[mid]) 然后显然它违反了因为它([l,r] 因为r 是相等的它可能是第一次出现)。

我是对的还是我没有正确理解不变量的概念?

【问题讨论】:

  • 我认为不变量应该是l &lt; x and r &gt;= x 然后最后返回r
  • @AndrewScoot 为什么我不能使用这个不变量?

标签: c++ algorithm binary-search invariants


【解决方案1】:

假设我们有一个序列

..., <q, <q, <q, q, q, ..., q, q, >q, >q, >q, ...
                 ^ (*)

其中&lt;q (&gt;q) 代表任何元素&lt; q (&gt; q)。我们想要找到点 (*)。

我们有两个指针,left &lt; right。我们如何使用它们来区分这一点?答案很简单:left 应该指向最后一个 &lt;q 元素,right 应该指向第一个 q 元素:

..., <q, <q, <q, q, q, ..., q, q, >q, >q, >q, ...
                 ^ right
             ^ left

不变量为:*left &lt; q*right &gt;= q

您建议的不变量 *left &lt;= q*right &gt; q 对应于该序列中的最后一个元素:

..., <q, <q, <q, q, q, ..., q, q, >q, >q, >q, ...
                                  ^ right
                               ^ left

一些有用的参考资料:

【讨论】:

  • 所以在这个问题中,我只能使用这个不变量==>"left=q" 对吗?
  • @AiraBanazadeh,如果你想找到第一个 q,是的。
  • 谢谢,我怎样才能找到这样的问题的不变量? (我的意思是我可以在你的答案中用你的逻辑解决并找到所有二进制搜索问题的不变量吗?)
  • @AiraBanazadeh,我不能说 all 二进制搜索问题,但想法始终相同。如果您想要更详细的解释,请查看我添加到答案中的一些参考资料。
  • 能把Programming Pearls的pdf链接提供给我吗?
猜你喜欢
  • 2015-05-17
  • 1970-01-01
  • 2019-04-13
  • 2019-11-06
  • 2021-11-15
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多