【为进大厂力扣刷题】6. 只出现一次的数字(异或位运算)

155 阅读1分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

一、题目描述:

136. 只出现一次的数字

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

说明:

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

示例 1:

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

示例 2:

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

二、思路分析:

解法1 异或位运算

不需要额外空间的方法,就往位运算上想

  1. 交换律:a ^ b ^ c <=> a ^ c ^ b
  2. 任何数于0异或为任何数 0 ^ n => n
  3. 相同的数异或为0: n ^ n => 0
var a = [2,3,2,4,4]

2 ^ 3 ^ 2 ^ 4 ^ 4 等价于 2 ^ 2 ^ 4 ^ 4 ^ 3 => 0 ^ 0 ^3 => 3
/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    let res = 0
    for(let i=0; i<nums.length; i++) {
        res ^= nums[i]
    }
    return res
};

解法2 排序

sort时间复杂度不稳定,因为chrome会根据元素个数采取不同的排序方案。

不符合题目但是也能解决~~

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    nums.sort()
    for(let i=1; i<nums.length; i+=2) {
        if(nums[i] !== nums[i-1]) return nums[i-1]
    }
    return nums[nums.length-1]
};

解法3 奇偶加减,非0返回

既然相同元素出现两次,排序后加一项减一项,和消消乐一样,每两项运算结果应该为0~~~

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    nums.sort()
    let res = 0
    for(let i=0; i<nums.length; i++) {
        if(i%2 == 0){
            res += nums[i]
        } else {
            res -= nums[i]
            if(res!==0){
                return nums[i-1]
            }
        }
    }
    return res
};