二分查找和不变关系

2023-11-24

我正在读这个post并试图弄清楚我们如何确定二分搜索的不变关系。具体来说,在他举的两个例子中,为什么这两个不变关系不同呢?是什么造成了不同?

A[start]

另一个问题是,我可以简单地将框架更改为:

int binarySearchFramework(int A[], int n, int target) {
    int start = start index of array - 1;
    int end = length of the A;
    while (end - start > 1) {
        int mid = (end - start) / 2 + start;
        if (A[mid] == target) return mid;
        if (A[mid] < target) {
            end = mid;
        } else {
            start = mid;
        }
    }      
   //not found
   ...
}  

这个是不是没有帖子里提供的那么好?

多谢!


你可以选择不变量。这是从实践中学到的技能。即使有经验,通常也会涉及一些尝试和错误。选一个。看看进展如何。寻找机会选择另一种需要较少维护工作的产品。您选择的不变量可以对代码的复杂性和/或效率产生显着的影响。

二分查找中的不变量至少有四种合理的选择:

a[lo] <  target <  a[hi]
a[lo] <= target <  a[hi]
a[lo] <  target <= a[hi]
a[lo] <= target <= a[hi]

您通常会看到最后一个,因为它最容易解释,并且不涉及使用超出范围的数组索引进行棘手的初始化,而其他方法则这样做。

现在那里is使用类似不变式的原因a[lo] < target <= a[hi]。如果你想永远找到目标重复系列中的第一个,这个不变量将执行 O(log n) 时间。什么时候hi - lo == 1, hi指向目标的第一次出现。

int find(int target, int *a, int size) {
  // Establish invariant: a[lo] < target <= a[hi] || target does not exist
  // We assume a[-1] contains an element less than target. But since it is never
  // accessed, we don't need a real element there.
  int lo = -1, hi = size - 1;
  while (hi - lo > 1) {
    // mid == -1 is impossible because hi-lo >= 2 due to while condition
    int mid = lo + (hi - lo) / 2;  // or (hi + lo) / 2 on 32 bit machines
    if (a[mid] < target)
      lo = mid; // a[mid] < target, so this maintains invariant
    else
      hi = mid; // target <= a[mid], so this maintains invariant
  }
  // if hi - lo == 1, then hi must be first occurrence of target, if it exists.
  return hi > lo && a[hi] == target ? hi : NOT_FOUND;
}

注意此代码未经测试,但应该按不变逻辑工作。

两个不变量<=只会发现some目标的实例。你无法控制哪一个。

这个不变量does需要初始化lo = -1。这增加了证明要求。你必须证明这一点mid永远不能设置为-1,这会导致超出范围的访问。幸运的是这个证明并不难。

你引用的那篇文章很糟糕。它有几个错误和不一致之处。在其他地方寻找示例。编程珍珠是一个不错的选择。

您建议的更改是正确的,但可能会慢一些,因为它将仅运行一次的测试替换为每次迭代运行一次的测试。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二分查找和不变关系 的相关文章

  • 实现快速 Javascript 搜索?

    基本上 我有一个带有文本框的页面和 ul 列在其下面 这 ul 由用户的朋友列表填充 用户开始在文本框中输入朋友的名字 例如按 r 我想立即更新 ul 每次按键仅显示名字以 R 开头的朋友 例如 Richard Redmond Raheem
  • 数组中连续元素的最大乘积

    我在现场面试的时候被问到了这个算法问题 由于没有要求我签署保密协议 我将其发布在这里寻求答案 给定一个数组REAL不包含 0 的数字 找到产生最大乘积的连续元素 该算法应在线性时间内运行 我考虑过以下方法 使用两个数组 第一个是利用DP思想
  • 如何仅使用单个数组在 JavaScript 中模拟调用堆栈

    我正在看维基百科页面 https en wikipedia org wiki Call stack在调用堆栈上 并尝试理解这个图像 据我所知 哈哈 const memory memory 0 3 top of stack pointer m
  • C 埃及分数

    古埃及人仅使用以下形式的分数1 n因此任何其他分数都必须表示为这些单位分数的总和 而且 所有单位分数都是不同的 在C或Java中使任何分数成为埃及分数 总和越少越好 的好方法是什么 可以使用什么算法 分支定界 a 例如 3 4 1 2 1
  • 快速约会算法

    我在一家咨询公司工作 大部分时间都在客户所在地 正因为如此 我很少见到同事 为了更好地了解彼此 我们将安排一个晚宴 会有很多小桌子 方便人们聊天 为了在聚会期间与尽可能多的不同的人交谈 每个人都必须每隔一段时间 比如每小时 换一张桌子 如何
  • 当搜索文本包含感叹号 (!)、与号 (&) 等时,IMAP“搜索标头”命令失败

    我正在通过 python 访问 GMail 的 IMAP 界面 我运行这样的命令 UID SEARCH HEADER Message ID email protected cdn cgi l email protection 成功 返回匹配
  • 异或交换可以扩展到两个以上的变量吗?

    我一直在尝试将异或交换扩展到两个以上的变量 例如n变量 但我没有得到比这更好的地方3 n 1 对于两个整型变量x1 and x2你可以像这样交换它们 swap x1 x2 x1 x1 x2 x2 x1 x2 x1 x1 x2 所以 假设你有
  • 使用并集查找(又名不相交集)检测图是否是二分图

    我正在 Spoj 上做一个问题 基本上可以简化为检测图是否是二分图 我正在尝试使用 dfs 为图表着色 但它太慢了 有人评论这个 没有 bfs 没有 dfs 没有二部图 简单的并查集就可以做到 确实速度很快 提示 1 偶数长度的环不会影响两
  • shell脚本中关联数组的时间复杂度

    我想知道在 shell 脚本中使用关联数组时如何构造 实现 另外 我想知道基于 shell 脚本的关联数组的时间复杂度是否是最佳的 因为我们可以使用字母和数字作为它们各自的键 编辑 他们使用什么哈希函数 如果您使用关联数组 则不能通过 使用
  • 找到一条穿过任意节点序列的最短路径?

    In 这个先前的问题 https stackoverflow com questions 7314333 find shortest path from vertex u to v passing through a vertex wOP询
  • 给定一个具有多个重复条目的数组,找到一个重复条目 O(N) 时间和常数空间

    我们得到了一个大小为 N 的数组 其中包含 0 到 N 2 范围内的整数 包括 0 和 N 2 该数组可以有多个重复的条目 我们需要在 O N 时间和常量空间中找到重复条目之一 我正在考虑取数组中所有条目的乘积和总和 以及 0 到 N 2
  • 归并排序中递归树的高度log(n)+1是怎么来的

    我按照 stackoveflow 的建议阅读了一些问题和答案 我正在遵循 cormen 的 算法简介 一书进行自学 那本书里已经解释得很清楚了 但唯一没有解释的是如何在合并排序分析中计算树的高度 如果在后面的章节中对此进行解释的话 我仍然在
  • 从一种数字系统转换为另一种数字系统后会有多少位数字

    主要问题 有多少位数字 让我解释 我有一个二进制数 11000000 十进制数是192 转换为十进制后 它有多少位 以十进制表示 在我的示例中 它是 3 位数字 但是 这不是问题 我在互联网上搜索并找到了一种用于整数部分的算法和一种用于小数
  • 在 O(n) 时间内排序?

    我被这个问题困扰了 2周 知道如何处理它吗 令 L 为 n 个不同整数的列表 假设 L 的 x 的元素在 1 750 范围内 设计线性排序算法对 L 的元素进行排序 我已经尝试过插入排序 但我不确定我的方法是否正确 Construct an
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • 在java中使用BUBBLE SORT对二维字符串数组进行排序

    类似的问题已经被问过 但从来没有关于二维字符串数组 因此在尝试了很长时间之后我找不到我想要的 我正在尝试使用 BubbleSort 对 java 中的 2D 字符串数组进行排序 作为输入 我收到一个二维字符串数组 一个表 以及您应该排序的
  • 如何用约束标记一大组“传递群”?

    在 NealB解决方案之后进行编辑 与以下解决方案相比 NealB的解决方案非常非常快任何另一个 https stackoverflow com q 18033115 answers and 提出了关于 添加约束以提高性能 的新问题 Nea
  • 需要解释搜索最小大和的算法

    我正在解决 Codility 问题作为练习 但无法回答其中一个问题 我在互联网上找到了答案 但我不明白这个算法是如何工作的 有人可以引导我逐步完成它吗 这是问题 You are given integers K M and a non em
  • 动态规划 (DP) 中的重叠子问题是什么?

    为了使动态规划适用 问题必须具有两个关键属性 最优子结构 and 重叠子问题 1 https en wikipedia org wiki Dynamic programming 对于这个问题 我们只关注后一个属性 有各种不同的定义重叠子问题
  • 谷歌如何通过图像进行搜索?

    最近 谷歌推出了图片搜索的新功能 即通过图片搜索 我们可以通过在谷歌搜索框中上传图片来搜索其他图片 这怎么可能 http images google com http images google com Look at WP 基于内容的图像

随机推荐