当前位置: 首页 > 面试题库 >

对具有重复项的排序数组使用二进制搜索

樊运乾
2023-03-14
问题内容

我的任务是创建一个方法,该方法将打印在排序数组中找到值x的所有索引。

我知道,如果我们仅从0到N(数组的长度)对数组进行扫描,则最坏情况下的运行时间为O(n)。由于将对传递给该方法的数组进行排序,因此我假设我可以利用二进制搜索的优势,因为这将是O(log
n)。但是,这仅在数组具有唯一值的情况下有效。因为二进制搜索将在特定值的第一个“查找”之后完成。我当时正在考虑进行二进制搜索,以便在排序后的数组中找到x,然后检查该索引之前和之后的所有值,但是如果数组包含所有x值,那么看起来并不会更好。

我想我要问的是,有没有一种更好的方法可以找到比O(n)更好的排序数组中特定值的所有索引?

public void PrintIndicesForValue42(int[] sortedArrayOfInts)
{
    // search through the sortedArrayOfInts

    // print all indices where we find the number 42. 
}

例如:sortedArray = {1、13、42、42、42、77、78}将输出:“在索引处找到42:2、3、4”


问题答案:

好吧,如果您确实有一个排序数组,则可以进行二进制搜索,直到找到您要查找的索引之一为止,然后从那里容易找到其余的索引,因为它们都紧挨着每个索引,其他。

找到第一个实例后,便要找到它之前的所有实例,然后再找到它之后的所有实例。

使用该方法,您应该大致得到 O(lg(n)+ k) ,其中 k 是您要搜索的值的出现次数。

编辑:

而且,不,您将永远无法在少于 O(k)* 时间的时间内访问所有 k个 值。 *

第二次编辑: 这样,我可以感觉到自己实际上正在贡献一些有用的东西:

不仅可以搜索X的第一个和最后一个出现,还可以对第一个出现进行二进制搜索,然后对最后一个出现进行二进制搜索。这将导致总数为 O(lg(n))
。完成此操作后,您将知道所有索引之间也都包含X(假设已排序)

您可以通过搜索值是否等于 x 检查左侧(或右侧,取决于您要查找的是第一个还是最后一个)来确定值是否等于 x



 类似资料:
  • 我想实现一种将排序数组插入二叉搜索树的算法,但我不希望最终得到一棵只向一侧生长的树。 你有什么想法吗? 谢谢你。

  • 问题内容: 我被要求对数组进行排序和搜索。对数组进行排序很简单,我的代码也起作用了,但是每当我尝试调用二进制搜索方法时,它就可以对数组中的第一个元素起作用,但是结果是“ -1” 我的完整代码如下: 问题答案: 您搞砸了二进制搜索间隔

  • 问题内容: 我在将这两种算法结合在一起时遇到麻烦。我被要求修改以返回将元素插入数组的索引。然后有人要求我实现一个使用my 对随机生成的数组进行排序的。 我按照预期的方式工作,每当我单独测试它时都返回正确的索引。我写信是为了了解它是如何工作的,并使其也能工作。一旦将两者结合在一起,它就会崩溃。我知道我在一起实施起来不正确,但是我不确定问题出在哪里。 这是我得到的: 我在运行它时得到的返回值是。有什么

  • 我正在处理一个Path方法,它返回从给定节点到具有给定值键的节点的路径。我的代码返回正确的数字,但它们在括号内。我如何拆下支架? 实际输出为: 但它应该是:

  • 考虑到这个问题:峰值元素是一个大于相邻元素的元素。 给定一个输入数组,其中num[i]≠ num[i 1],找到一个peak元素并返回其索引。 该数组可以包含多个峰值,在那种情况下将索引返回到任何一个峰值都是精细的。 示例:Array=[1,4,5,7,4,3,1]。峰值指数=3(即7)。 下面的代码非常有效(不仅仅适用于此测试用例): 我不明白它是如何工作的——我以为二进制搜索只是用于排序数组/

  • 一个痛苦而愚蠢的问题,我几乎羞于不敢问。在过去的4个小时里,我一直在寻找,测试了不同的算法,在纸上尝试了不少,但仍然无法正常工作。 我将为您提供项目实现的详细信息,但基本问题是:“如何处理在预排序二叉树中插入节点。 通过预排序BST,我的意思是所有节点都应该以这样的方式插入,即使用预排序遍历(例如用于打印)遍历树时,应该按升序打印节点。 我只需要一个简单的算法。我尝试了这里给出的一个简单的插入算法