【问题标题】:find a single element in an array of consecutive duplicate elements在连续重复元素的数组中查找单个元素
【发布时间】:2015-07-10 20:01:36
【问题描述】:

给定一个元素数组,其中每个元素都重复,除了单个元素。而且所有重复的元素都是连续的。

我们需要找出那个单一元素的索引。

注意:

  1. 数组可能没有排序

  2. 预计时间 O(logn)

  3. 元素范围可以 做任何事。

O(n) 是微不足道的。但我怎样才能弄清楚logn? 也考虑了按位运算符,但没有解决。

另外,我无法在这个问题中使用这个陈述所有重复的元素都是相互连续的。

Ex:  2 2 3 3 9 9 1 1 5 6 6
     output 5

【问题讨论】:

  • 如果数组没有排序,你不能在 O(n) 之内做到这一点,因为你必须知道每个元素才能给出答案。如果它是排序的,可能有一个可用的快捷方式,但我想不出它。
  • 如果数组是排序的,那么我们肯定可以使用二分查找,但是对于未排序的数组,可能是任何其他数据结构都可以做到...任何特定的树 AVL、红黑等。
  • 其实我错过了重复元素总是连续的事实。在那种情况下,是否排序并没有区别,但我仍然想不出比 O(n) 更好的解决方案。
  • 哦,它们是不是重复了两次?如果每个项目不能超过 2 个,那就很容易了。只需对差异从偶数索引切换到奇数索引的点进行二分搜索。
  • 不明白,如何应用二分查找?

标签: c++ algorithm data-structures


【解决方案1】:

这可以通过检查 arr[2k] == arr[2k+1], k>=0 是否在 O(logn) 中完成 - 如果是,则不同的元素在 2k+1 之后,如果不是 - 则在 2k+1 之前。

这使您可以通过检查中间值在每一步有效地修剪一半数组,并仅递归一半大的问题,得到O(logn) 整体。

Python 代码:

def findUnique(arr,l,r):
    if r-l < 2: 
        return (arr[l],l)
    mid = (r-l)/2 + l
    if mid % 2 != 0:
        flag = -1
    else:
        flag = 0
    if (mid == 0 or arr[mid-1] != arr[mid] ) and (mid == len(arr)-1 or arr[mid] != arr[mid+1] ):
        return (arr[mid],mid)
    if arr[mid+flag] == arr[mid+1+flag]:
        return findUnique(arr,mid,r)
    return findUnique(arr,l,mid)

【讨论】:

  • 这意味着如果我们不知道它们重复了多少次,它就无法在 O(logn) 中以任何方式解决?
  • @Prashant 如果所有元素的重复次数为m&gt;1,则可以在O(logn+m)内完成,而且我们不需要提前m,只要找到找出m 是什么(通过查看第一个m+1 项目),并通过检查arr[k*m]arr[a*m + m-1] 重复相同的过程。
【解决方案2】:

假设每个元素恰好重复两次,除了一个,那么这很容易。 第一个答案是正确的,只是觉得我可以详细说明一下。

那么,让我们以您的示例数组为例。

a = [2 2 3 3 9 9 1 1 5 6 6];

如果所有元素都配对,那么你可以取一个偶数索引并确定下一个元素将是相同的。

a[0] = 2;
a[1] = 2; //as well
a[2] = 3;
a[3] = 3; //as well

一般情况:

a[k] = a[k+1] = x; 

其中 k 是偶数,x 是某个值。

但是,在您的情况下,我们知道有一个索引不遵循此规则。 为了找到它,我们可以使用Binary Search(仅供参考),中间有一些额外的计算。 我们走到中间的某个地方,抓取一个具有偶数索引的元素。 如果该元素的值等于下一个元素的值,则您的 lonely 值位于数组的第二部分,因为配对尚未中断。 如果这些值不相等,那么你的 lonely 值要么在前半部分,要么你在它(它在中间)。

您需要在前后检查几个元素以确保。

通过在每次迭代中将数组减半,您将获得 O(logn) 时间。

【讨论】:

  • 第一个答案毫无疑问是正确的。我只是觉得我可以添加一些额外的解释。 :)
猜你喜欢
  • 2019-09-30
  • 2019-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多