蓝桥杯题解(Java):找出唯一成对的数

找出唯一成对的数

1-1000这1000个数放在含有1001个元素的数组中,只有唯一的个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

代码

/**
 * 1-1000这1000个数放在含有1001个元素的数组中,只有唯一的
 * 个元素值重复,其它均只出现一次。每个数组元素只能访问一次,
 * 设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
 */
public class 找出唯一成对的数 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 6};
        int N = arr.length;

        // 方式一:
        int x1 = 0;
        // 先将 1~1000 的两两异或,得到 x1
        for (int i = 1; i <= N - 1; i++) {
            x1 = x1 ^ i;
        }
        // 将 x1 与 arr数组 中的每个值异或
        for (int i = 0; i < N; i++) {
            x1 = x1 ^ arr[i];
        }
        System.out.println(x1);

        System.out.println("===========");

        // 方式二:
        int[] helper = new int[N];
        for (int i = 1; i <= N - 1; i++) {
            helper[arr[i]]++;
        }
        for (int i = 1; i <= N - 1; i++) {
            if(helper[i] == 2) {
                System.out.println(i);
                break;
            }
        }
    }
}

优解思路

根据异或(^)运算的性质,x ^ x = 0 以及 x ^ 0 = x ,可以得出两个相同的 x 做异或运算可以起到 去除重复 的目的。因为只有一个数字是成对的,我们将数组中的所有元素做异或运算,去除掉的便是所要求的数字。

我们可以单纯地将1~1000每一个数字去做异或运算,得到一个结果,再与数组中的每个元素做异或运算。给定数组中仅有一个的元素,会在这一次的异或运算中变为0而去除掉。而本身在数组中重复的元素,会出现三个相乘的情况(若重复数字为 x ,那么会出现 x ^ x ^ x = x 的现象),那么此时,最后留下的数字便是所求结果。

总结

异或运算有去重复的作用,且不需要再开辟新的空间

暴力思路

首先得明确一点:数组的下表往往是有意义的。我们可以这样来想:

我们先创建一个数组,将给定的数组元素,当作新数组的下标,新数组元素的值作为出现的次数。

举例子:

给定的数组为:{1, 2, 3, 4, 5, 3}。那么,我们创建长度相同的数组,数组下标为0的位置我们不使用,直接从下标为1开始使用,newArr[1] = 1; newArr[2] = 1; newArr[3] = 2; newArr[4] = 1; newArr[5] = 1;。所以,新数组中的 newArr[3] 的数组下标即为所要求的唯一成对的数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值