# 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2, 2, 1]
输出: 1

示例 2:

输入: [4, 1, 2, 1, 2]
输出: 4

# JavaScript

解法 1:

利用按位异或(每一个对应的位,两个不相同则返回 1,相同则返回 0)满足交换律和结合律的特性,可以将遍历数组进行异或求值,最终得到的即为只出现一次的数。

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
  return nums.reduce((a, b) => a ^ b)
}

解法 2:

利用 HashMap 的方法是最容易想到的,我们直接遍历数组将每个数字出现的次数存到哈希表里就可以了,然后我们再从哈希表里找出只出现一次的那个数。

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
  var map = {}

  for (let index = 0; index < nums.length; index++) {
    const item = nums[index]

    if (!map[item]) {
      map[item] = 1
    } else {
      map[item]++
    }
  }

  var keys = Object.keys(map)

  for (let index = 0; index < keys.length; index++) {
    const key = keys[index]

    if (map[key] === 1) {
      return key
    }
  }
}

解法 3:

利用 Stack 可以先对数组进行排序,然后遍历数组。

如果栈为空则将当前元素压入栈,如果栈不为空,若当前元素和栈顶元素相同则出栈,继续遍历下一元素,如果当前元素和栈顶元素不同的话,则说明栈顶元素是只出现一次的元素。

若遍历到最后尚未找到,则留在栈顶的元素就是只出现一次的元素。

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
  const sortedNums = nums.sort()
  const stack = []

  while (sortedNums.length) {
    const now = sortedNums.shift()

    if (stack.length) {
      const pre = stack.shift()

      if (pre === now) {
        continue
      }

      return pre
    } else {
      stack.unshift(now)
    }
  }

  return stack[0]
}

解法 4:

我们可以首先对数组进行求和得到 Total,然后利用 Set 去除重复的元素后再进行求和得到 setTotal。因为我们其他元素都出现两次,仅有一个元素出现一次,那我们通过 $setTotal*2-Total$ 得到的元素则为出现一次的数。

# 参考