题目链接
题目 数组中只出现一次的数字【中等】
一个整型数组里除了两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例
示例 1:
输入:sockets = [4, 5, 2, 4, 6, 6]
输出:[2,5] 或 [5,2]
示例 2:
输入:sockets = [1, 2, 4, 1, 4, 3, 12, 3]
输出:[2,12] 或 [12,2]
提示: 2 <= sockets.length <= 10000
题解
位运算
- 时间复杂度是O(n)
- 空间复杂度是O(1)
/**
* @param {number[]} sockets
* @return {number[]}
*/
var sockCollocation = function(sockets) {
let x = 0, y = 0, n = 0, m = 1;
for(let num of sockets) { // 1. 遍历异或
n ^= num;
}
while((n & m) == 0) // 2. 循环左移,计算 m
m <<= 1;
for(let num of sockets) { // 3. 遍历 sockets 分组
if((num & m) != 0) { // 4. 当 num & m != 0
x ^= num;
} else { // 4. 当 num & m == 0
y ^= num;
}
}
return [x, y]
};
哈希表
我们也可以用哈希表来解决这个问题。
首先,我们可以创建一个哈希表hash,用来存储数组中的数字及其出现次数。
然后,我们可以遍历数组,对于每个数字num,我们可以判断num是否在哈希表中。
如果num在哈希表中,说明num出现了两次,我们可以把num从哈希表中删除。
如果num不在哈希表中,说明num出现了一次,我们可以把num加入哈希表。
最后,我们返回[a, b]。
- 时间复杂度是O(n)
- 空间复杂度是O(n)
/**
* @param {number[]} sockets
* @return {number[]}
*/
var findNumbers = function(sockets) {
let hash = {};
for (let num of sockets) {
if (hash[num]) {
delete hash[num];
} else {
hash[num] = true;
}
}
let a = 0, b = 0;
for (let num in hash) {
if ((num & a) === 0 && b === 0 ) {
b ^= num;
} else {
a ^= num;
}
}
return [a, b];
}