• 异或


    从LeetCode的一道题说起:

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

    说明:

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

    由于算法薄弱,刚开始想到的是列表的count方法,然而直接报出超出时间限制的错误,各路大神也都纷纷给出方法,哈希或者循环出两个集合相减等。但是我感觉最具典型算法思想的是数学计算法和异或,先来看下用数学方法怎么解:

    给定一个数组arr,用集合给数组去重:set(arr),然后对集合求和*2,减去数组arr的和:2(a+b+c)(a+a+b+b+c)=c

    然后另一种方法就是异或,先看下异或的一些知识。

    异或是一种基于二进制的位运算,用符号XOR或者 ^ 表示,其运算法则是对运算符两侧数的每一个二进制位,同值取0,异值取1。它与布尔运算的区别在于,当运算符两侧均为1时,布尔运算的结果为1,异或运算的结果为0。所以异或是一种不进位加法,如1+1=0,,0+0=0,1+0=1。

    性质:

    1、交换律(a^b==b^a)

    2、结合律(即(a^b)^c == a^(b^c))

    3、对于任何数x,都有x^x=0,x^0=x

    4、自反性 A XOR B XOR B = A xor  0 = A

    用法:

     在C语言中,若需要交换两个变量的值,除了通常使用的借用中间变量进行交换外,还可以利用异或,仅使用两个变量进行交换:

    A = A XOR B

    B = B XOR A

    A = A XOR B

    好吧,我承认刚看到上面句子的时候一脸懵B,换个写法会好很多:

    a = A XOR B

    B = B XOR a = B XOR A XOR B = A

    A = a XOR B = A XOR B XOR A = B

    这样写更容易理解。

    十进制的异或

    现实中用的都是十进制的数值,那么我们来看一看两个十进制数值是怎么进行异或计算:

    5 ^ 3 = ?

    进行异或前需要把两个数转换为二进制:0101   0011

      0101
    XOR 0011
    ------  
    结果 0110

     

     

     

    将0110转换为二进制:6

    既有5 ^ 3 = 6

    解题:

    如上,对异或有了简单了解后,上面的题目也可用异或解决:

    def singleNumber(arr):
        a = 0
        for i in arr:
            a = a^i
        return a
    

     

    终日不为以思,无益,不如学也
  • 相关阅读:
    招聘 微软全球技术支持中心 sql server组
    retrofit2 上传图片
    android 6.0权限判断 音频 拍照 相册
    android studio 修改成自己jks(keystore)签名文件
    android 透明度颜色值
    android studio clone 失败
    fresco Bitmap too large to be uploaded into a texture
    android 虚线
    EventBus 3.0使用
    java.lang.IllegalArgumentException: You must not call setTag() on a view Glide is targeting
  • 原文地址:https://www.cnblogs.com/lymlike/p/11790732.html
Copyright © 2020-2023  润新知