给定一个数组A,其中所有元素出现两次,但一个元素只出现一次。我们如何找到在O(logn)时间内只出现一次的元素?我们来讨论两个案例。
我只能提出在整数的二进制表示中使用XOR运算符的解决方案,如Here所述,最后,二进制字符串将表示仅出现一次的元素,因为重复将取消。但这需要O(n)时间。我们怎么能做得更好呢?
答案 0 :(得分:2)
如果元素已排序,和元素的范围和差异已知,那么我认为与binary search不同的策略可以在 O(logN)时间。在您的问题中,第一个案例或多或少符合这些要求。
考虑数字介于[1,M]之间的情况,并且每个连续的不同值具有K的差异。然后您知道在没有唯一元素的数组中,每个索引(2i,2i + 1) )将包括元素(1 + K i,1 + K i)。在包含唯一元素的数组中,它将是(1 + K *(k-1),1 + K * i)。使用该信息,类似于二进制搜索的搜索算法可以找出唯一元素所在的数组的一半,并在 O(logN)时间内到达它。
为了演示我上面提到的索引概念,请参阅您自己的示例。在唯一元素的左侧(即3),所有索引对(2i,2i + 1)具有相同的值。并且所有子索引从索引0开始并以索引位于唯一元素右侧结束,所有索引对(2i,2i + 1)都对应于包含不同值的单元格。
除非我在回复开始时提到的条件存在,否则你必须调查每一个元素,我相信你提出的任何算法至少需要花费O(n)时间。这就是你在问题中提到的第二种情况。
答案 1 :(得分:2)
在一般情况下,这是不可能的,为了确保元素不重复,您需要检查每个其他元素。
从您的示例中,似乎数组可能是整数的排序序列,没有“间隙”(或其他明确定义的序列,如所有偶数等)。在这种情况下,可以使用修改的二进制搜索。
你有阵列[1,1,2,2,3,4,4,5,5,6,6]。
检查中间元素及其后面的元素并查看3和4.现在您知道集合{1,2,3}中只有5个元素,而集合中有6个元素{4,5 ,6}。这意味着,缺少的元素在{1,2,3}中。
然后你递归[1,1,2,2,3]。你看2,2。现在你知道有2个“1”元素和1个“3”元素,所以答案就是3个。
你在每一步中检查2个元素的原因是,如果你只看到“3”,你不知道你是否击中了“3,3”或第二个中的前3个。但是如果你读了2个元素,你总会发现2个不同元素之间的“边界”。
这是可行的条件是,给定元素的值,您需要能够在O(1)中计算在此元素之前有多少不同的元素。在你的情况下,这是微不足道的,但它也可以用于任何算术系列,几何系列(具有固定大小的数字)......
答案 2 :(得分:-1)
我不相信有一个O(log n)解决方案。原因是为了找到哪一个元素只出现一次,至少需要迭代该数组的元素一次。