您的位置:首页 > 其它

找出数组中唯一的重复元素

2012-09-24 19:15 232 查看

找出数组中唯一的重复元素※

1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次.每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

(1) 方法一:(当N为比较大时警惕溢出)

将1001个元素相加减去1,2,3,……1000数列的和,得到的差即为重复的元素。

int Find(int* a)

{

int i;

for (i = 0;i<=1000;i++)

a[1000] += a[i];

a[1000] -= (i*(i-1))/2 //i的值为1001

return a[1000];

}

(2) 方法二:

数组取值操作可以看做一个特殊的函数f:D→R,定义域为下标值0~1000,值域为1到1000.如果对任意一个数 i,我们把f(i)叫做它的后继,i叫f(i)的前驱。0只有后继没有前驱,其他数字既有后继也有前驱,重复的那个数字有两个前驱,我们将利用这些特征。

规律:从0开始画一个箭头指向它的后继,从它的后继继续指向后继的后继,这样,必然会有一个节点指向之前已经出现过的数,即为重复的数。

利用下标与单元中所存储的内容之间的特殊关系,进行遍历访问单元,一旦访问过的单元赋予一个标记,利用标记作为发现重复数字的关键。代码如下:

void FindRepeat(int array[], int length)

{

int index = 0;

while ( true )

{

if ( array[index]<0 )

break;

array[index] *= -1; //访问过,变成相反数

index=array[index]*(-1);

}

cout<<"The repeat number is "<< -array[index] <<endl;

}

(3) 方法三

同样考虑下标与内容的关系,不过不用标记,而用两个速度不同的过程来访问。Slow每次前进一步,fast每次前进两步。在有环结构中,它们总会相遇。

void FindRepeat(int array[], int length)

{

int slow=fast= 0;

while ( true ) {

slow = array[slow];

fast = array[array[fast]];

if( slow == fast )

break;

}

fast = 0;

while( true) {

slow= array[slow];

fast =array[fast];

if( slow == fast )

break;

}

cout<<"The repeat number is "<< array[slowendl;

}

(4) 方法四:异或操作

void FindRepeat(int array[], int length)

{

int result = 0;

for(int i=1;i<=1000;i++)

result ^= i;

for(int i=0;i<=1000;i++)

result ^= array[i];

cout << result << endl;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: