• 异或


    从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
    

     

    终日不为以思,无益,不如学也
  • 相关阅读:
    Spring AOP获取拦截方法的参数名称跟参数值
    mybatis generator逆向工程自动生成带中文注释修改版(添加了实体类注释)文末附有git下载地址
    关于Java编写多行注释遇到方法字符串中正好也有注释符号产生冲突的解决办法
    SpringBoot入门学习以及整合MyBatis
    IO跟NIO的区别
    redis的配置文件详解redis.conf
    Redis入门基础内容(转载整理非原创)
    深入网络协议来理解数据传输三(http协议详解)
    深入网络协议来理解数据传输二(转载整理)
    Python编写ATM(初级进阶)
  • 原文地址:https://www.cnblogs.com/lymlike/p/11790732.html
Copyright © 2020-2023  润新知