题目:找到重复的数
在 1 到 n 的数字中,有且只有唯一的一个数字 m 重复出现了,其他的数字只出现了一次,请把这个数找出来。
方法解析:
需要考虑不同的数量级,分两种情况:
1. 内存能容纳这n个数
方法1:暴力查找,两层循环遍历,时间复杂度为O(n^2),空间复杂度为O(1)
方法2:用快排先进行排序,然后遍历一次,比较前一个数和后一个数,若相等,则查找完成,时间复杂度O(nlogn),空间复杂度为O(1)
方法3:利用hash表(或set),进行一次遍历,同时将遍历到的数放入hash表,放入之前判断hash表是否存在,若存在,则找到了重复的数,时间复杂度为O(n),空间复杂度为O(n)
方法4:使用位向量,遍历给到的n个数,对于出现的数,将对应位标记为1,如果已经是1则查找成功,时间复杂度为O(n),空间复杂度为(n),这种方法类似方法3,虽然渐进的空间复杂度和方法3相同,但是其实小很多很多,毕竟只要用1bit就能表示有或无
2. 内存无法容纳给到的n个数
依然可以用上述方法4来解决,其它的方法有的不能用,有的效率不高。
利用异或:
根据异或的两个特点,任何两个相同的数异或的结果都为0,任何数与0异或都为这个数,因此将所有的数依次异或得到的结果就是除了两个重复数的所有数的异或结果,假设为T。
而将1到n依次异或的结果为T^重复数。因此,重复数=T^T^重复数。即:所有数异或的结果再异或1到n所有数异或的结果
首先是异或运算满足交换律、结合律。
所以,1^2^...^n^...^n^...^1000,无论这两个n出现在什么位置,都可以转换成为1^2^...^1000^(n^n)的形式。
其次,对于任何数x,都有x^x=0,x^0=x。
所以1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n)= 1^2^...^1000^0 = 1^2^...^1000(即序列中除了n的所有数的异或)。
令,1^2^...^1000(序列中不包含n)的结果为T
则1^2^...^1000(序列中包含n)的结果就是T^n。
T^(T^n)=n。
所以,将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。