只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
示例:
输入: [4,1,2,1,2]
输出: 4
实现:
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var singleNumber = function(nums) {
if (nums.length < 2) {
return nums[0];
}
nums.sort((a,b)=>(a-b));
let single = null;
nums.reduce(function(pre,cur,index,nums){
if (index === 1) {
if ((nums[index-1] - cur) !== 0) {
single = nums[index-1];
}
} else if (index < (nums.length - 1)) {
if ((nums[index-1] - cur) * (nums[index+1] - cur) !== 0) {
single = cur;
}
} else {
if (cur - (nums[index - 1]) !== 0) {
single = cur;
}
}
});
return single;
};
我一看,用了100多ms,只超过了62.62%,于是点开了用时几十ms的解答,开启了懵的大门。。。
var singleNumber = function(nums) {
let result = 0;
nums.forEach(el => (result ^= el));
return result;
};
看了好几个,全都是使用 ^
来解答的,看不懂,搜了一圈,知道 ^
是位运算 XOR,二进制表示下,当只有一个数位存放的是 1 时,它才返回 1。
那又怎么样呢,把每个数都转成二进制?❓❓❓
脑子完全被二进制的疑惑给塞满了,4 ^ 1 = 5, 5 ^ 2 = 7, 7 ^ 2 = 5
, ❓❓❓
实在是很懵了,就跑去问大佬了,大佬给我解释了一通,我开始还是没转过弯,后来突然明白了!
因为对正整数n来说,n ^ n = 0, 0 ^ n = n,为什么是这样的呢?
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
XOR = 0000 0000 0000 0000 0000 0000 0001 1010
位运算 XOR,二进制表示下,当只有一个数位存放的是 1 时,它才返回 1,不论n转为二进制之后是什么, n ^ n 每一位的操作数都是相同的,因此结果的每一位都会是0,最终结果也是0,类似的道理,可以得出 0 ^ n = n 的结论。
而 nums.forEach(el => (result ^= el));
,就是将数组中的每一个元素连着进行XOR操作,
不论顺序如何,两个相同的数XOR运算的最终结果都是0,最终留下的就是那个只出现一次的数字了。
被这个骚操作彻底折服!