面试100题系列之7找出N个连续的数中缺失的数

一、找出N个连续的数种缺失的一个数
首先数组乱序,没有告诉连续的数的范围,所以先扫描一遍数组,找出min和max。
如果max-min+1 <= N,说明缺失的数据在两个端点。等于N说明缺失的数据在max和min之间。
下面介绍两个比较好的方法:
1、对数据进行求和,min~max的和为(max+min)N/2,算出数组中所有元素的和,相减就可以得到缺失的数据了。
PS:如果min和max的跨度比较大,也就是说求和可能会导致数据溢出,那么可以一边加一边减,即从min开始加到max,min-a[0]+min+1-a[1]....+max-a[n-1];
2、将数组中的元素全部进行异或运算,再异或上min^(min+1)^....^max。这样就相当于求2n+1个数,2n个成对出现,找出只出现一次的数。
二、题目扩展:数组中缺失两个数?
假设已经扫描了一遍数组,得到了数据的范围min和max,并且已经确定了缺失的数据是在中间而不是在两段。怎么判断应该很简单吧,直接max-min就OK了。
同样的可以用两种方法:
1、对数据从min~max求和,为S1,并且求出数组中所有元素的和,为S2,记缺失的数据为a,b。S1-S2=a+b;那么a、b,一定是一个比(a+b)/2小,一个比它大。OK。在遍历一遍数组,以(a+b)/2为分界线,较小的加为Smin,较大的加为Smax。求出min~(a+b)/2和(a+b)/2~max的和,相减就可以得到两个数了。
2、将数组中的元素全部进行异或运算,再异或上min^(min+1)^....^max,这样就得到了a^b,记为c。由于a!=b。所以c!=0;那么一定有一位是1.用d=(c-(c&(c-1)))就可以得到c的最右边的为1的位,以这一位为分界线,为1的分为一组,不为1的分成另一组,然后求min~d和d~max的异或,再分别异或上刚刚分好的两组数据。这样就将问题转化成问题1的情况了。那a、b自然也就出来了。
三、那如果缺失三个数据呢。
OK,同样的方法,就不用我多说了。

你可能感兴趣的:(面试笔试)