leetcode-136-只出现一次的数字

158 阅读1分钟

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

说明:

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

示例 1:

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

示例 2:

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

题解:

  1. 使用集合

用一个集合帮助存储,遍历数组,如果集合中存在该元素,则取出来,如果不存在则存进去。出现两次的元素会先存进去再取出来,只有出现一次的元素会存进去,因此最终集合中剩下的元素就是只出现一次的元素。

var singleNumber = function (nums) {
  var numberSet = new Set();
  for (var i = 0; i < nums.length; i++) {
    if (numberSet.has(nums[i])) {
      numberSet.delete(nums[i]);
    } else {
      numberSet.add(nums[i]);
    }
  }
  return numberSet.values().next().value;
};
  1. 使用字典

使用一个dict来记录每个数字出现的次数,最后找到只出现一次的数字

var singleNumber = function (nums) {
  var numberObj = {};
  for (var i = 0; i < nums.length; i++) {
    numberObj[nums[i]] = numberObj[nums[i]] ? numberObj[nums[i]] + 1 : 1;
  }
  return Object.entries(numberObj).find(([key, value]) => value === 1)[0];
};
  1. 集合 + 和

使用集合和存储数组中的数字,分别对集合和数组求和,由于只有一个元素出现了一次,因此数组的和将比集合的和的2倍小一点,小的正是只出现一次的数字。

var singleNumber = function (nums) {
  var numberSet = new Set();
  var arraySum = 0;
  var setSum = 0;
  for (var i = 0; i < nums.length; i++) {
    numberSet.add(nums[i]);
    arraySum += nums[i];
  }
  for (var num of numberSet) {
    setSum += num;
  }
  return setSum * 2 - arraySum;
};
  1. 使用异或操作
  • 任何数和0做异或都等于其本身,a⊕0=a
  • 任何数和本身做异或都等于0, a⊕a=0
  • 异或运算满足交换律和结合律,a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b
var singleNumber = function (nums) {
  var result = 0;
  for (var i = 0; i < nums.length; i++) {
    result ^= nums[i];
  }
  return result;
};

原题目 js的按位操作符