zoukankan      html  css  js  c++  java
  • 异或

    从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
    

     

    终日不为以思,无益,不如学也
  • 相关阅读:
    cf D. Vessels
    cf C. Hamburgers
    zoj 3758 Singles' Day
    zoj 3777 Problem Arrangement
    zoj 3778 Talented Chef
    hdu 5087 Revenge of LIS II
    zoj 3785 What day is that day?
    zoj 3787 Access System
    判断给定图是否存在合法拓扑排序
    树-堆结构练习——合并果子之哈夫曼树
  • 原文地址:https://www.cnblogs.com/lymlike/p/11790732.html
Copyright © 2011-2022 走看看