位运算的妙用 1

这个系列主要是记录作者本人在学习算法过程中的一些总结

首先呢,我们通过一道题来引出今天所讲到的技巧:

看到这道题,大家会考虑怎么做,我第一次想出的答案就是直接求和,然后减去真正的1~1000数字的和,最后得到的那个数字就是所求,直接暴力求解,哈哈,但是具有局限性,所以就来给大家分享一个很巧妙的方法。
在此之前,大家先学习一下这些位运算的操作符
在这里插入图片描述
这道题呢,我们主要是运用 ^ 运算符去求解,也就是左右两个数相同时结果为 0 ,不同时结果为 1,从而达到去重的效果,但是这道题要求的是求出重复的数字,不是正好反着来了吗?所以,就用这数组中1001个元素去与1~1000的数字去 ^ 那么1001中1 ~ 1000的数字就都出现了两次,通过亦或运算符消除掉了,而原来数组中重复的元素加起来出现了三次,两个被去重了,剩下那个就被留下来了,这一点希望大家好好理解一下

我们先假设重复的是3
在这里插入图片描述
前面每个元素和后面的进行亦或,都被消掉了
在这里插入图片描述

用代码来表示就是:

public class FindRepeat {
    public static void main(String[] args) {
        int N = 11;
        int[] arr = new int[N];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i + 1;
        }
        //生成1~10的随机数,作为重复的那个元素,暂时放在数组末位
        arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;
        //生成一个随机下标
        int index = new Random().nextInt(N);
        //将重复的元素与随机出来的下标所在元素互换
        swap(arr, index, arr.length - 1);
        System.out.println(Arrays.toString(arr));
        int x1 = 0;
        //1~10之间亦或
        for (int i = 1; i <= N - 1; i++) {
            x1 = x1 ^ i;
        }
        //接着找出重复元素
        for (int i = 0; i < N; i++) {
            x1 = x1 ^ arr[i];
        }
        System.out.println(x1);

    }
    //交换元素
    public static void swap(int arr[], int index1, int index2) {
        int temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }
}

在这里插入图片描述
结果就是这个样子的,这里数组里边是11个元素,为了方便大家查看,解题时大小改为1001就可以了

代码中通过生成的随机数来作为重复的元素,先把这个元素放在数组末位,再与随机的一个数组下标所指元素交换,从而打乱重复元素所在位置,之后先把1~10之间元素亦或,再将结果与数组中所有元素亦或,也就是之前我们分析的那样

除了这个方法,还有一个开辟辅助空间的方法,当然,题中要求的是不能开辟辅助空间,这里只是分享一下一个暴力破解的方法,如果上面讲的方法想不到,还可以多一种方法

 //开辟辅助空间的方法
        int[] helper = new int[N];
        //在遍历arr数组的同时,利用下标,给helper数组赋值,两次++的为重复元素
        for (int i = 0; i < N; i++) {
            helper[arr[i]]++;
        }
        for (int i = 0; i < N; i++) {
            if (helper[i] == 2) {
                System.out.println(i);
                break;
            }
        }

这个方法呢,巧妙的利用了下标的关系来进行求解,因为是1~1000的数字加上一个重复的数字,那么 arr[ i ] 中所记录的元素作为数组helper 的下标 ,也不用担心数组越界的问题,最终helper数组中最后一个位置并没有被赋值,为0,其他位置都被赋值为了1,而因为有一个重复的元素,所以helper
数组中有一个元素被赋值了两次,变为了2,遍历找出该元素,那个 i 就是重复的元素
在这里插入图片描述
运行之后也是没有问题的,结果是两个方法的运行结果,大家区分一下
在这里插入图片描述
本次分享的两个方法掌握之后,再遇到类似的题也可以求解了

在这里插入图片描述
例如这个题,比我们提到的例题还简单一点,并没有过多的要求,大家可以尝试一下。

后续还会持续更新,有什么问题可以在评论区留言哦,有报名了蓝桥杯的小伙伴也可以一起督促学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值