找出数组中唯一出现k次的元素x
1.问题描述
面试中常见的一类题目,给定一个数组,数组中的元素出现的次数规律,找出某个出现固定次数的元素X。
比如:
题目1:数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次。请给出最快的方法,找到x。
题目2:一个数组A,数字出现的情况,只有以下三种:一些数字只出现一次;一些数字出现两次;只有一个数字出现三次。
总结上面的题目,可以得到下面的框架:给定数组A,其长度为n,其中出现
编号 | n | 1次 | 2次 | 3次 | 目标 |
1 | n>=3 | 1 | n-1 | 0 | 找出出现1次的元素 |
2 | n>=4 | 1 | 0 | n-1 | 找出出现1次的元素 |
3 | n>=6 | a>=1 | b>=1 | 1 | 找出出现1次的元素 |
2. 解法
方法1:统计法,就是统计每个元素的出现次数,然后在输出相应次数的元素。一般使用hash map来进行统计。时间复杂度O(n),空间复杂度O(n)。这是一种通用的解法,对表中的三种情况都适用,缺点是空间复杂度高
方法2::排序法,就是先对数组进行排序,然后从头到尾遍历依次查找相应次数的元素。时间复杂度O(nlogn),空间复杂度O(1)。这也是一种通用的解法,对上面表中的三种情况都适用,缺点是时间复杂度高
方法3:对1和2两种情况,使用一个长度为32的数组,按照bit位进行分别统计,再根据统计次数的性质来得到结果。这种方法之所以可行是因为1和3互质,1和2互质,在统计结果里面各个bit位之间是没有影响的。时间复杂度O(n),空间复杂度O(1)。
方法4:在方法3中,其实我们没有必要统计出所有bit的次数。对情况1中,我们只需要判断出现次数的奇偶性就行了,所以用一个整数就可以表示了。对情况2,我们只需要查看每个bit上1出现的次数是否为3的倍数,所以只要用两个整数就可以了。时间复杂度O(n),空间复杂度O(1)。
方法5:在方法4的基础上,对情况1的继续优化。使用XOR的特性,把所有的n个元素进行XOR运算,结果就是所求目标。因为出现2次的元素,XOR运算后就会变为0,且不影响其他元素的元算。此时,出现1次可以推广到奇数次,出现2次可以推广到偶数次。时间复杂度O(n),空间复杂度O(1)。
3. 一个扩展题目
一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字。
解法:首先对原数组进行全部元素的异或,得到一个必然不为0的结果,然后判断该结果的2进制数字中,为1的最低的一位。然后根据此位是否为1,可以把原数组分为两组。则两个不同的元素,必然分别在这两个数组中。然后对两个数组,进行异或操作,即可得到所求。
4. 总结
(1)XOR的作用:A xor A = 0 Axor 0 = A,可以用来区分奇偶,相当于进行过滤。
(2)对于数组来讲,可以看成一个bit的矩阵,数组的长度相当于列数,数的位度相当于高度。
5. 参考资料
(2)http://blog.csdn.net/wangwh485/article/details/6715357
(3)http://t.cn/z8O9icZ?u=1915548291&m=3622390980872175&ru=1915548291&rm=3621285189572151