您的位置:首页 > 其它

使用“初中知识”实现查找重复最优算法 + 最终极限算法

2009-08-08 16:39 375 查看
这是园子里讨论了好长时间的题目了:
1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
发起文章:算法题,求高手. 作者: 莫贝特(MBetter)
算法改进:利用异或的特性解决,找出重复数的问题,应该是目前最优算法。 作者:Ivony...

莫贝特给出的算法是:将所有数加起来,减去1+2+...+1000的和
Ivony给出的算法是: 将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数
两位算法的时间复杂度都是: 2n (莫贝特的算法可以用高斯算法简化)

我把题目扩展了一下,将1000换成n,让些题更通用一些:
1-n放在含有n+1个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?(n可能为奇数)(注意:数组是无序的,有序数组很好解决不讨论)

下面是我的算法,先给出代码,c#语言

public static int GetRepeated(int[] array)
public static int GetRepeated2(int[] array)
{
int temp = 0;
for (int i = 0; i < array.Length; i++)
temp += array[i] - i ;
return temp;
}算法原理:改进莫贝特的算法,加减加减加减...,而不是(加加加...)减(加加加...)。出现溢出的可能性也小了很多!
更是精简,强人!!

不甘落后,我用lambda再改进一下:

public static int GetRepeated3(int[] array)
{
return array.Select((i, j) => i - j).Sum();
}简单说明一下:
方法三中的“i”相当与方法二中的“array[i]”;
方法三中的“j”相当于方法二中的“i”

其它大可不必写成一个函数,像下面这样直接调用就好了,也算是最后的极限算法了。

int repeatedNum = array.Select((i, j) => i - j).Sum();array就是包含n+1个数的数组,repeatedNum就是其中唯一重复的数。这应该是极限了吧!

大家可以调试运行一下这几种方法都可以通过,有问题拍我。

本人系列文章《c#扩展方法奇思妙用》,敬请关注!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: