java位运算的奇巧淫技相关算法题目详解
涉及知识点见博客:java位运算的奇巧淫技
位相关算法题目
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
思路: 使用多次异或可以实现去重
例如:按照题意,假设现在有ABCD四个字母放在5个元素的数组中,假设数组是ACCBD,我们把数组的元素互相异或,即A^C^C^B^D
,然后再紧接着异或一遍ABCD,即A^C^C^B^D^A^B^C^D
,那么根据异或的交换律,这个式子就可以变成A^A^C^C^C^B^B^D^D
,根据性质:“自己异或自己结果为零”,原式就可以化为0^0^C^0^0
,最后的结果就为C,C恰恰就是我们要找的重复的那个数。
代码
import java.util.Scanner;
//异或去重
public class Demo01 {
public static void main(String[] args) {
//输入满足题意的数组
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数组元素的个数");
int n = scanner.nextInt();
int[] arr = new int[n];
System.out.println("请输入规范的元素(从1开始依次输入到 " + (n-1) + " 有一个重复的)");
for (int i = 0; i < arr.length; i++) {
arr[i] = scanner.nextInt();
}
//异或去重算法
//用来异或的初始值0,因为0异或上任何数还是原来的数;可以理解为乘法时的初始变量值为1,因为1乘任何数还是原来的数
int x=0;
//第一遍异或,让数组内的元组自己互相异或
for (int i = 0; i < arr.length; i++) {
x = x^arr[i];
}
//第二遍异或,让前面的式子再异或上从1到n-1(因为n为元素的个数,其实最大的值为n)
for (int j = 1; j <= arr.length-1; j++) {
x = x^j;
}
//输出结果
System.out.println("重复的元素为:" + x);
}
}