使用位运算找出数组中的“单身狗”

1,711 阅读2分钟

前言

在算法题中,我们经常会碰到使用位运算来进行解题的情况。今天我们通过一道寻找“单身狗”的题,来简单熟悉一下位运算。

示例

一个数组中包含一个或多个正整数,其他数字都出现两次,只有一个数字出现了一次,请找出只出现了一次的数字。

例如:

[2, 2, 1, 3, 1, 5, 4, 5, 4] -> 3

[2] -> 2
function uniqueNumber(nums) {
  // write code
}

题解1

使用一个对象进行存储,存储每个整数出现的次数。再对对象进行遍历,找出出现次数为1的数即可。

function uniqueNumber(nums) {
  let obj = {}
  for (let n of nums) {
    if (obj[n]) {
      obj[n]++
    } else {
      obj[n] = 1
    }
  }
  for (let i in obj) {
    if (obj[i] === 1) {
      return Number(i)
    }
  }
}

console.log(uniqueNumber([1,2,2,1,3,3,4,4,5]))  // 5

题解2

使用位运算的异或操作(用符号^表示),异或操作会比较 数字二进制相同的位数上的数,相同就是 0,不同就是 1

  1. 异或运算满足交换律:a^b^c === c^b^a

  2. 两个相同的数异或等于 0:a^a === 0

  3. 任何一个数和 0 异或等于原数:a^0 === a

在知道了异或操作之后,对于此题使用异或是不是就有思路了。我们只需依次对每个数执行异或运算,由于相同的两个数异或为 0,只有一个出现次数为1的数,最终异或的结果就是我们要找的数。

function uniqueNumber(nums) {
  let res = 0
  for (let n of nums) {
    res ^= n
  }
  return res
}

console.log(uniqueNumber([1,2,2,1,3,3,4,4,5])) // 5

题解3

除了使用 for 循环之外,也可以使用 reduce 配合异或运算,一行代码解决。

function uniqueNumber(nums) {
  return nums.reduce((a, b) => a ^ b, 0)
}

console.log(uniqueNumber([1,2,2,1,3,3,4,4,5])) // 5

最后

如果你对此题有不同的解法,欢迎在评论区发表~