[算法] 找出丢失的数字

有一组数字,从1到n中减少了一个数,顺序也被打乱了,放在一个n-1的数组里,请找出丢失的数字。

  1. 用1+2+...+n(即n(n+1)/2)减去当前输入数据的总和。时间复杂度为O(n),空间复杂度O(1),缺点是容易溢出。缓解溢出的方法,求1+2+...+n的时候,边加边减。假如数组为a,那么这可以这么计算1-a[0]+2-a[1]+...+(n-1)-a[n-2]+n。
  2. 用1*2*...*n除以当前输入的数据的积。时间复杂度O(n),空间复杂度O(1)。缺点也是容易溢出,缓解的办法:1/a[0]*2/a[1]...(n-1)/a[n-2]*n(得用浮点除法)。
  3. 用1^2^...^n逐个异或当前输入数据。时间复杂度为O(n),空间复杂度O(1)。这是比较完美的解决办法,不存在溢出的问题。
  4. 对输入数据排序,然后从头到尾遍历一次。时间复杂度O(nlgn),空间复杂度O(1)(还取决于排序算法)。缺点很明显,时间复杂度过高。
  5. 对输入数据进行Hash,然后从头到位遍历一次。时间复杂度O(n),空间复杂度O(n)。

问题扩展1:如果是少了两个数,那又该怎么办呢?

假设丢失的两个数为x和y。

  1. 用1+2+...+n减去当前输入数据的总和,可以得到x+y;用减去当前输入数据的平方和可以得到。联立两个方程可以得到x和y。时间复杂度O(n),空间复杂度O(1)。问题是容易溢出。
  2. 用1+2+...+n减去当前输入数据的总和,可以得到x+y;用1*2*...*n除以输入数据的积可以得到xy。联立可以得到x和y。时间复杂度O(n),空间复杂度O(1)。缺点是容易溢出。
  3. 对输入数据排序,然后从头到尾遍历一次。时间复杂度O(nlgn),空间复杂度O(1)。
  4. 对输入数据进行Hash,然后从头到尾遍历一次。时间复杂度O(n),空间复杂度O(n)。
  5. 用1^2^...^n的结果逐个异或当前输入数据,得到x^y。由于x与y不相等,所以x^y的结果中至少有一位是1。我们根据这一位的不同(0或1)将输入数据以及1,2,...,n分成两堆。然后,分别对两堆进行异或即可得到x和y。

问题扩展2:1-1000放到含有1001个元素的数组中,只有唯一的一个元素重复,其他均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来。要求不用辅助存储空间。

这个问题的解法类似,用1^2^...^1000的结果逐个异或输入的1001个元素,得到的结果即为所求。

相似问题:

  1. 给你n个数,其中有且仅有一个数出现了奇数次,其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那一个数。
  2. 给你n个数,其中有且仅有两个数出现了奇数次,其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那两个数。

posted on 2011-03-30 11:39  小橋流水  阅读(813)  评论(0编辑  收藏  举报

导航