OnlyOneNum

OnlyOneNum

所有元素都是成对的,只有一个元素是单一的,求问如何在O(N)的复杂度里面找出这个元素


如果没有时间限制的话当然是个很简单的问题,但是在O(N)时间内得出结果,就有点难了。我们不妨通过看看二进制的角度来看看。
用累异或的方法实现。举个栗子🌰,[2,3,2,3,5],2的二进制为0010,3的二进制为0011,假设数组全是成对出现的那么无论什么顺序,最终累异或的结果一定为0(0000)。Show you the code.

1
2
3
4
5
6
7
int singleNumber(int[] nums) {
int result = 0;
for (int i = 0; i < nums.length; i++) {
result ^= nums[i];
}
return result;
}

拓展

如果有两个元素是单一的

思路是将元素分为两组,每组都有一个单一的元素,则通过同理一步就OK了。
问题是怎样才能将两个单一元素分为两组呢?
首先重复第一步操作,因为有两个独立的元素,那么结果中所有位上至少有一个为1,那么我们就可以将这个位上为1的分为一组,为0的分为一组。
再举个栗子🌰,[2,2,3,4,3,5],4的二进制为0100,5的二进制为0101,最终异或的结果为0001,那么从右数第一位上为1的分为一组[3,4,3],为0的分为一组[2,2,5]。然后就和上面的一样了。


如果所有元素不是成对,而是奇数,比如三对三对出现

这样子就不能按之前的方法去做了。我们可以这么想,假如都是成三对出现的,那么除去独立的元素,所有成对的元素按位累加,那么每位的个数都是3n。所以我们把所有元素按位累加,哪一位上的数是3n±1,就是这个独立元素的。(用这种方法也可以解第一题……)