leetcode每天一题:【只出现一次的数字】(简单)

651 阅读2分钟

这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战

题目描述

leetcode题目地址

给一个数组,都是有值的,整数类型,里面的整数,有一个只出现一次,其它都是出现了两次。现在需要找出那个出现了一次的整数,并且返回它。

举个例子:

arr: [1,2,1]
返回 2

arr: [1,2,3,2,3]
返回 1

arr: [2,2,3,4,3,5,4]
返回 5

思路分析

第一种方法

这个是找出只出现一次的元素,我们可以新建个对象(也可以用Map)做映射

遍历数组,以数组的值做key,1 做value, 每次遍历都要判断对象是否存在该key,如果存在则以 2为value。

最后对对象遍历,找到value等于 1 的key,这个就是只出现一次的数字,返回即可。

代码如下:

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function (nums) {
  const obj = {}
  for (let i = 0; i < nums.length; i++) {
    if (obj[nums[i]]) obj[nums[i]] = 2
    else obj[nums[i]] = 1
  }
  for (let key in obj) {
    if (obj[key] === 1) return key
  }
};

image.png

这里又有个需求,如果不能利用额外空间,可否实现呢?

答案是可以的。

第二种方法

因为只有一个数字出现1次,其它都出现2次,那么我们对数组进行排序,如果一个数跟它前后都不相等,则证明它只出现一次,对吧?

有个特殊情况,就是首尾需要单独做判断,因为首的话它没有前的元素,尾的话它没有后的元素。

其它情况判断前后元素是否相等就行了。都不相等的话返回即可。

代码如下:

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function (nums) {
  nums.sort((a, b) => a - b)
  // 首尾需要特别判断
  for (let i = 0; i < nums.length; i++) {
    if ((i === 0 && nums[i] !== nums[i + 1]) || i === nums.length - 1 && nums[i - 1] !== nums[i]) return nums[i]
    if (nums[i] !== nums[i - 1] && nums[i] !== nums[i + 1]) return nums[i]
  }
};

image.png

第三种方法

第三种方法,利用异或运算符(^)

异或运算符, 会先把数转成二进制再比较, 0和1异或,值为1,1和1,或者0和0异或,值为0。

所以两个相同的数异或,最后返回结果是0。

因为我们题目的数组其它数都是出现2次,只有一个出现一次。所以我们遍历数组异或,出现2次的数异或都变成0,最后就等同于出现一个的数字和0异或,返回还是数字本身。

代码如下:

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
  let temp = 0;
  for (let i = 0; i < nums.length; i++)
    temp ^= nums[i];
  return temp;
}

image.png