给你一个整数数组
nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。
因为是常量额外空间,然后成对的数不需要考虑,就应该想到通过异或的运算,这样就得到了最后两个不一样的元素的异或值,因为不一样,所以这个结果一定有一位是1,(如果全是0就是一样的元素了)。
然后再次遍历,对应位置上是1的放一边进行异或,是0的放另一边进行异或。这样就得到了结果。
/**
* @param {number[]} nums
* @return {number[]}
*/
var singleNumber = function (nums) {
let xorAll = 0;
for (const x of nums) {
xorAll ^= x;
}
// Math.clz32(xorAll) 是求32位2进制数的前导零的个数,如果用32去减就得到了第一个1的位置(从后往前数,比如 1101,第一个1从后往前就是4,我们用31 去减,就是3,因为我们要把右边的三个数给干掉)
const shift = 31 - Math.clz32(xorAll);
const ans = [0, 0];
for (const x of nums) {
// 对于任意一个数,右移三位,得到第四位及前面的数,再与 1 并一下,只得到第四位,此时要么是 1 ,要么是 0,正好对应我们希望的arr的两个结果的位置,分组异或即可
ans[(x >> shift) & 1] ^= x;
}
return ans;
};