Algorithm 查找给定数组中的两个重复元素

Algorithm 查找给定数组中的两个重复元素,algorithm,Algorithm,您将获得一个由n+2个元素组成的数组。数组的所有元素都在1到n的范围内。除两个数字出现两次外,所有元素都出现一次。找出两个重复的数字 例如,array={4,2,4,5,2,3,1}和n=5 伙计们,我知道这个问题的4个可能的解决方案,但最近我遇到了一个我无法解释的解决方案。下面是解决方案的算法 traverse the list for i= 1st to n+2 elements { check for sign of A[abs(A[i])] ; if positive then m

您将获得一个由n+2个元素组成的数组。数组的所有元素都在1到n的范围内。除两个数字出现两次外,所有元素都出现一次。找出两个重复的数字

例如,array={4,2,4,5,2,3,1}和n=5

伙计们,我知道这个问题的4个可能的解决方案,但最近我遇到了一个我无法解释的解决方案。下面是解决方案的算法

traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
   make it negative by   A[abs(A[i])]=-A[abs(A[i])];
else  // i.e., A[abs(A[i])] is negative
   this   element (ith element of list) is a repetition
}
Example: A[] = {1,1,2,3,2}
i=1 ; A[abs(A[1])] i.e,A[1] is positive ; so make it negative ;
so list now is {-1,1,2,3,2}

i=2 ; A[abs(A[2])] i.e., A[1] is negative ; so A[i] i.e., A[2] is repetition,
now list is {-1,1,2,3,2}

i=3 ; list now becomes {-1,-1,2,3,2} and A[3] is not repeated
now list becomes {-1,-1,-2,3,2}

i=4 ;
and A[4]=3 is not repeated

i=5 ; we find A[abs(A[i])] = A[2] is negative so A[i]= 2 is a repetition,

This method modifies the original array.

这个算法是如何产生正确的结果的,即它是如何工作的。大家不会把这个问题当作家庭作业问题,因为这个问题最近在微软的采访中被问到了。

你所做的是以两种方式使用数组值:它们有一个数字和一个符号。您“存储”在数组的第n个点上看到一个数字
n
,而不会丢失该点的原始区域值:您只是在更改符号

你从所有正数开始,如果你发现你想要“保存”你看到的当前值的事实的索引是allready负数,那么这个值已经allready被看到了

例如: 所以如果你第一次看到4,你就把第四个点的符号改成负号。这并没有改变第四个位置,因为当你去那里的时候,你正在使用[abs],所以不用担心。
如果你看到另一个4,你再次检查第四个点,看到它是负数:presto:a double。

当你在位置i中找到某个元素,比如说n,那么你使
a[abs(a(i))]=a[abs(n)]
为负数。因此,如果您找到另一个包含n的位置j,您还将检查
A[abs(A(j))]=A[abs(n)]
。因为您发现它是负数,所以n重复:)

您将得到一个n+2的数组 元素。数组的所有元素 在1到n的范围内。以及所有元素 发生一次,除了两个数字 发生两次

让我们稍微修改一下,只使用
n
,而不是
n+2
,然后问题陈述的第一部分就变成了

给您一个n的数组 元素。数组的所有元素 在1到n的范围内

现在你知道你有了一个数组,数组中的数字从1开始,数组中的每一项都增加1。因此,如果有10项,数组将包含数字1到10。5项,你有1到5项,以此类推


因此,可以使用存储在数组中的数字对数组进行索引。i、 你可以说
A[A[i]]
在这里,我简单,使用哈希表

对于每个项目,检查它是否已经存在O(1),如果不存在,则将其添加到哈希表O(1)


当您找到已存在的项目时。。。就这样

我知道这并不是你问题的答案,但如果我真的要在一个真实的项目上写这段代码,我会从一个排序算法(如quicksort)开始,在我的比较函数中

int Compare(int l, int r)
{
    if(l == r)
    {
        // duplicate; insert into duplicateNumbers array if it doesn't exist already.
        // if we found 2 dupes, quit the sort altogether
    }
    return r - l;
}

我会将其放入“性能和可维护性之间的良好平衡”的可能解决方案中。

@leppie这是另一个问题,因为有两个问题重复出现numbers@belisarius:抱歉:)向上投票反对“关闭”投票。@leppie我也被诱惑了:D.顺便说一句,这个算法很聪明…@belisarius:我没有试图理解它,它的复杂性是什么?它与使用合并排序然后使用简单遍历(即
O(nlogn)
)的解决方案相比如何?@leppie:主题相同,但问题不同。你可能的复制品是在寻求解决方案(而你的是优秀的+1 BTW)。这个问题要求解释具体的解决方案。对我来说,只有你的解释才能理解其他解释。感谢Binary Worrier的清晰解释。@yogi15490:不客气,先生(如果你很高兴这回答了你的问题,你可以将其标记为已接受的答案,谢谢)。
int Compare(int l, int r)
{
    if(l == r)
    {
        // duplicate; insert into duplicateNumbers array if it doesn't exist already.
        // if we found 2 dupes, quit the sort altogether
    }
    return r - l;
}