分而治之算法 - 二分搜索变体

Posted

技术标签:

【中文标题】分而治之算法 - 二分搜索变体【英文标题】:Divide and Conquer Algorithms- Binary search variant 【发布时间】:2016-03-11 06:29:35 【问题描述】:

这是一个理解分治算法的练习题。

给定一个由 N 个排序整数组成的数组。所有元素都是不同的,除了一个 元素重复两次。设计一个 O (log N) 算法来找到该元素。

我知道该数组需要被划分,看看是否在下一个索引中找到了相等的对应物,我相信这是二进制搜索的一些变体。但我找不到任何解决方案或指导。

【问题讨论】:

这些是连续整数吗? 没有。这是问题的确切文本,它没有提到连续的整数。 当不是连续的数字时,我认为没有logN解决方案。 要实现 log(N),您需要一些标准来在每次迭代时丢弃一半数组。对于随机(尽管已排序)整数,没有这样的标准,您最终需要检查所有元素,这使得最坏的情况为 O(N)。可能问题的作者正在考虑一个由 1..N-1 个元素组成的数组(即连续的)。 这似乎与连续数字问题太相似了,可能是因为错误而遗漏了,因为如果不是 - 那么连续排序数组问题具有冗余信息,它不会:) 【参考方案1】:

您不能在 O(log n) 时间内完成此操作,因为在任何步骤中,即使您将数组分成两部分,您也无法决定要考虑哪些部分进行进一步处理,哪些部分应该留下。 另一方面,如果连续的数字都存在于数组中,那么通过查看索引和索引中的值,我们可以确定重复的数字是在数组的左侧还是右侧。

【讨论】:

【参考方案2】:

D&C 应该是这样的

int Twice (int a[],int i, int j) 
    if (i >= j)
       return -1;
    int k = (i+j)/2;
    if (a[k] == a[k+1]) 
       return k;
    if (a[k] == a[k-1])
       return k-1;
    int m = Twice(a,i,k-1);
    int n = Twice(a,k+1,j);
    return m != -1 ? m : n;



int Twice (int a[], int n) 
    return Twice(a,0,n);

但它的复杂度为 O(n)。如上所述,对于这个问题,不可能找到 O(lg n) 的算法。

【讨论】:

以上是关于分而治之算法 - 二分搜索变体的主要内容,如果未能解决你的问题,请参考以下文章

分而治之的算法(二分搜索的应用?!)

算法复习_分治算法之二分搜索棋盘覆盖快速排序

你能写出满分的二分查找算法吗

递归迭代和分治:分治与二分查找

C语言中的分而治之二分查找

如何在数据库索引中使用二进制搜索