记一次XOR(异或)的应用

题目的要求是:

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

示例 1:

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

示例 2:

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

说明:

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

分析

虽然可以借助键值对等数据结构(java中的map,python中的字典)来完成这题,但终究还是使用了额外的空间。

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        temp = {}
        for i in range(len(nums)):
            temp[nums[i]] = temp.get(nums[i], 0) + 1
        
        for key in temp:
            if temp[key] ==  1:
                return key
        return -1

要做到在不使用额外的空间、且保证线性复杂度的情况下,完成这道题,只能用位运算中的异或了(^)

先来回顾一下位运算的基本判定方法

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

符合的运算定律

1、可交换

a ^ b = b ^ a

2、可结合

a ^ b ^ c = a ^ ( b ^ c )

3、与自身的运算一定为false(0)

a ^ a = 0

4、任何值与0异或,都等于这个数的本身

a ^ 0 = a

 

综合考虑上述的几个定律,这一题就不难了。

a ^ b ^ a ^ b ^ c ^ c ^ d ^ e ^ e

= a ^ a ^ b ^ b ^ c ^ c ^ e ^ e ^ d  (定律1)

= ( a ^ a ) ^ ( b ^ b ) ^ ( c ^ c ) ^ ( e ^ e )  ^ d   (定律2)

= 0 ^ 0 ^ 0 ^ 0 ^ d   (定律3)

= 0 ^ d (定律4)

=d

只要将这个数组中所有的数做与或运算,就可以找到落单的那个

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """

        res = 0
        for var in nums:
            res ^= var
        return res

异或在加密和备份等领域都有使用,感兴趣可以访问下面参考链接中的博客。

参考: http://www.ruanyifeng.com/blog/2021/01/_xor.html

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值