算法题_位运算_1_成对出现的数

位运算

成对出现的数

最近在学习数据结构与算法,对算法题真的是又爱又恨,有些觉得挺有趣的,有时抓破头都想不出,这道题算是基础的入门题,我也才刚刚开始学,所以记录一下。

题目:寻找数组中唯一成对出现的数
要求:1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
/**
 * @author Zhang
 * @date 2022/3/3 16:16
 * @description 唯一成对的数
 */
public class 唯一成对的数 {
    public static void main(String[] args) {
        /*
         * 首先我们先来创建一个满足要求的数组
         * 1000个数组,调试起来,不太方便,因此,我们以20个数来举例子
         * 倘若无误,只需将N的值换为1001即可
         */
        int N = 21;
        int[] arr = new int[N];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i + 1;
        }
        //随机放入一个1 ~ N-1的数
        arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;
        //随机下标
        int index = new Random().nextInt(N);

        //交换arr.length - 1 和 index 两个索引下标的值
        Util.swap(arr, index, arr.length - 1);
        System.out.println(Arrays.toString(arr));
        
        //至此,我们已经构建出一个满足题目要求的数组,接下来我们来看看,如何解题
    }
}

1.1、解法1:辅助空间

辅助空间法(注:不符合题目要求,仅供学习)

方法描述:
    1、另外开辟一个容量为1001的数组tempArr
    2、遍历目标数组,将目标数组的元素出现时,tempArr数组对应下标的的元素值+1,即tempArr[arr[i]]++
    3、再次遍历tempArr数组,输出元素值为2的元素 
public class 唯一成对的数 {
    public static void main(String[] args) {
        //构建题设数组……
        
        //解法1:辅助
        //题目说不能使用空间,故不能使用此方法,但是我们可以用来学习比较
        //创建一个数组,假设为B,利用数组B的下标来存放原数组元素出现的次数
        int[] tempArr = new int[N];
        for (int i = 0; i < arr.length; i++) {
            tempArr[arr[i]]++;
        }
        for (int i = 0; i < tempArr.length; i++) {
            if (tempArr[i] == 2) {
                System.out.println("重复的数:" + i);
                break;
            }
        }
    }
}

1.2、解法2:异或

首先我们先来简单了解一下位运算中“异或”运算。

异或:可以理解为不进位加法,1^1=0, 0^0=0, 1^0=1
    性质:
    1、结合律,可以交换运算因子的位置,结果不变
    2、结合律,即(a^b)^c = a^(b^c)
    3、对于任何数x,都有x^x = 0, x^0 = x。即,同自己求异或为0,同0求异或为自己
    4、自反性,A^B^B = A^0 = A
public class 唯一成对的数 {
    public static void main(String[] args) {
        //构建题设数组……
        
        //解法2:异或,利用 A^0=A, A^A=0, A^B^B^C^C = A^0^0 = A
        //因此“异或”运算,在求 重复数字 或者 去除重复数字 的题目中有奇效
        //算法:(1^2^...^k^...^k^...^N) ^ (1^2^...^k^...^N)
        //1、先计算N个数的异或(后面部分)
        for (int i = 1; i < N; i++) {
            xi = (xi ^ i);
        }

        //2、再计算数组的元素的异或(前面部分)
        for (int i = 0; i < arr.length; i++) {
            xi = (xi ^ arr[i]);
        }
        System.out.println("重复的数:" + xi);
    }
}

运行结果:
在这里插入图片描述


如有错误,敬请指正!!!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

窝在角落里学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值