异或应用小总结

本文介绍了位操作在解决特定问题中的高效应用,如快速交换变量、查找数组中缺失的整数、找出数组中唯一出现一次的数等。还提供了LeetCode题目Find the Difference的解决方案,展示了异或运算的独特魅力。
摘要由CSDN通过智能技术生成

转载自:https://blog.csdn.net/hulamua/article/details/52411446

1.交换

交换a和b的简单写法

  1. a ^= b;

  2. b ^= a;

  3. a ^= b;

2.一个整形数组,存1到n的所有整数,但缺省一个值,找出此值。

先求1到n的异或,再和数组中所有数异或,结果就是要找的值。

3.一个整形数组除一个数只出现一次外,其余的都出现2次,求这个数

数组中所有值进行异或即可。

4.一个整形数组除两个数只出现一次外,其余的都出现2次,求这两个数。

若求所有数的异或,得出的是那两个数的异或值,这样没法分出两数。

有两种方法:(1)不同的两个数进行异或,肯定有至少1位为1。比如,这两个数的二进制为1101和0001,异或结果为1100。那么找出这个1,就可以把整个数组分为两部分,再利用2中的方法一一找出。

 

<pre name="code" class="java">public static void findTwoNumber(int[] a) {

     int sum = 0;

     for (int i = 0; i < a.length; i++) {

          sum = sum ^ a[i];

     }

     int bit = 1; // 从最低位,即0001开始找

     while (true) {

          if ((sum & bit) != 0)

          {

              break; // 通过与bit相与,找出异或后为1的那一位

          }

          else

          {

              bit = (bit<<1);

          }

       }

     int re1 = 0;

     int re2 = 0;

     for (int i = 0; i < a.length; i++) {

          if ((bit & a[i]) != 0) { // 利用与bit相与是否为0将数组分成两部分

               re1 ^= a[i];

          } else {

               re2 ^= a[i];

          }

     }

     System.out.println(re1 + " " + re2);

}

(2)将所有数异或,得出的值为a^b,再一一和数组中的值进行异或,得出的每个值存入一个list,由于两个数之外的值出现两次,判断数组中若已存在此值,将其删掉,最后list中就只有两个值,即为a与b

public static void findTwoNumber(int[] a) {

     int sum = 0;

     for (int i = 0; i < a.length; i++) {

          sum = sum ^ a[i];

     }

     List<Integer> list = new ArrayList<Integer>();

     for (int i = 0; i < a.length; i++) {

          int u = sum ^ a[i];

          if (list.contains(u)) {

               list.remove(Integer.valueOf(u));

          } else {

               list.add(u);

          }

     }

     System.out.println((list.get(0)) + " " + (list.get(1)));

}

5.一个整形数组除3个数只出现一次外,其余的都出现2次,求这3个数。
将所有数异或,得出的值sum为a^b^c,再一一和数组中的值进行异或,得出的每个值存入一个list。将出现两次的值删掉,最后list中就只有三个值:a^b,a^c,b^c,三值与sum异或,即得c,b,a三个数。同理可求4个或更多出现一次的数。

public static void findThreeNumber(int[] a) {

     int sum = 0;

     for (int i = 0; i < a.length; i++) {

          sum = sum ^ a[i];

     }

     List<Integer> list = new ArrayList<Integer>();

     for (int i = 0; i < a.length; i++) {

          int u = sum ^ a[i];

          if (list.contains(u)) {

               list.remove(Integer.valueOf(u));

          } else {

               list.add(u);

          }

     }

System.out.println((sum ^ list.get(0)) + " " + (sum ^ list.get(1)) + " " + (sum ^ list.get(2)));

}

6.Leetcode389.Find the Difference

String s 和 String t仅含小写字母字符,其中t是s的重排且加了一个字符,找到那个新加入的字符。题意示例:

Input:
s = "abcd"
t = "abcde"

Output:
e

对s和t的每个字符异或。

public static char findTheDifference(String s, String t) {

     char a = 0;

     for (int i = 0; i < s.length(); i++) {

          a ^= s.charAt(i); // 异或

     }

     for (int i = 0; i < t.length(); i++) {

          a ^= t.charAt(i);

     }

     return a;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值