剑指offer_56_数组中数字出现的次数I【javascript】

124 阅读1分钟

题目链接

leetcode.cn/problems/sh…

题目 数组中只出现一次的数字【中等】

一个整型数组里除了两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是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];
}