异或运算

一、异或运算(无进位运算)

  参加运算的两个对象,按照二进制位进行异或运算,运算规则:0^0=0,0^1=1,1^1=0,相同为0,不同为1

  异或运算的性质:

  • 任何一个变量与0异或是其本身(N^0=N)
  • 任何一个变量与自身异或为0(N^N=0)
  • 异或运算满足交换律和结合律

二、使用场景

  • 不使用额外变量,进行两个变量值的交换,前提两个变量不能指向同一个内存地址(在数组中使用必须考虑)
    
    
    public static void main(String[] args) {
    int a = 11;
    int b = 20;
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    System.out.println("a: " + a + ", b: " + b);
    }

     

  • 一个数组中出现某个数出现奇数次,其余数字出现偶数次,找出奇数次的数字。(要求时间复杂度:O(n), 空间复杂度:O(1))

    public static int findOdd(int[] arr) throws Exception {
            if (arr == null) {
                throw new Exception("arr 不符合要求");
            }
            int eor = 0;
            for (int item : arr) {
                eor = eor ^ item;
            }
            return eor;
        }

     

  • 一个数组中出现某两个数出现奇数次,其余数字出现偶数次,找出奇数次的数字
    public static void findOddNum2(int[] arr) {
            int eor = 0;
            for (int item : arr) {
                eor ^= item;  // 这里最终结果为 eor = a ^ b
            }
    
            // 由a != b, eor != 0 -> eor某一个位置上必然是1, 即 a, b必然有一个位置上是1和0
            // 取最右的1
            int rightOne = eor & (~eor + 1);
            int onlyOne = 0;
            for (int cur : arr) {
                if ((cur & rightOne) == 1) { // 说明cur相同位置为1
                    onlyOne ^= cur;
                }
            }
            System.out.println(onlyOne + "," + (eor ^ onlyOne));
        }

     

        
posted @ 2021-11-30 11:47  Shydow  阅读(5851)  评论(0编辑  收藏  举报