利用位运算找出数组中唯一成对的数

一、位运算前导知识
(一)异或^
  1. 定义:不同为1,可以理解为不进位的加法, 1+1=0, 0+0=0,1+0=1
  2. 性质:
    • 交换律
    • 结合律
    • 对于任何数x,都有x^x=0,x^0=x
    • 自反性A^B^B=A^0=A,连续和同一个因子做异或运算,最终结果为自己
  3. 应用:
    • 判断奇偶数
    • 交换两个整数变量的值
    • 获取二进制位是1还是0
    • 不用判断语句,求整数的绝对值
二、找出唯一成对的数
  1. 题目:将1-1000的数字存放在含1001个元素的数组中,只有唯一的一个元素值重复,找出该数。不使用额外的辅助空间,且数组的每个元素只能访问一次。
  2. 思路:利用异或位运算的性质,偶数个相同的数做异或位0,奇数个相同的数做异或为该数本身,即3^3=0, 3^3^3=3
1)假设重复的数为k且1<=k<=1000,得有1001个元素的数组为[1, 2, 3, ..., k, k, ..., 999, 1000] 
2)构造异或的辅助数据,1^2^3^...^k^...^999^1000,从11000的异或
3)用数组与辅助数据做异或(1^2^3^...^k^k^...^999^1000)^(1^2^3^...^k^...^999^1000) = k

3.代码:

import java.util.Random;

public class 唯一成对的数 {
    public static void main(String[] args) {
        method1();
    }

    public static void swap(int[] arr, int i, int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static void method1(){
        int N = 1001;
        int[] arr = new int[N];
        //构造数据
        for (int i = 0; i < arr.length -1; i++) {
            arr[i] = i + 1;
        }
        arr[arr.length - 1] = (new Random().nextInt(N - 1)) + 1; //构造重复的数
        System.out.println("重复元素: " + arr[arr.length-1]);
        //随机存放重复元素
        int index = new Random().nextInt(N);
        swap(arr, index, arr.length -1);

        //1.构造异或串(1^2^……^N-1)
        int tmp = 0;
        for(int i = 1; i <= N -1; i++){
            tmp = (tmp ^ i);
            //System.out.println((tmp ^ i));
        }

        //2.去除不重复的数据 arr ^ (1^2^……^N-1)
        //元素个数为偶数则去除该元素,奇数则保留
        for(int num : arr){
            tmp = num ^ tmp;
        }
        System.out.println(tmp);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值