错题修订1------位运算实现元素查找

题目

给定一个整数数组,其中正好两个元素只出现一次,所有其他元素恰好出现两次。查找仅出现一次的两个元素。(使用位运算实现)

思路

首先要先明白一个知识:
异或相同为0,不同为1

	n ^ 0 = n;
	n ^ n = 0;

我们可以据此,先将整个数组的元素依次进行一次异或操作,得到最终的异或值。(两个相同的数字进行异或之后,会得0,而0异或任何数字得到该数字的本身,所以这个数组最后的异或值会为那两个不重复数字的异或值)

	int temp = 0;
	for (int i = 0; i < nums.length; i++) {
	    temp ^= nums[i];
}

得到那两个恰好只出现一次的元素的异或值后,开始两个元素划分的准备工作。
temp为二者异或值,异或是不同为1,可根据此为切入点来进一步操作。我们可以将temp和temp的相反数进行与运算,得到其异或值为1的最低位。(取最低位是因为方便)
正数的原码、反码、补码一致;负数在计算机中用补码进行运算,即负数绝对值原码取反后再+1------注意:如果要负数的原码,需要将求得的补码视为原码,再求补码
一个数和它的相反数进行与运算,能得到恰好一位为1,其余全为0

	//Integer.MIN_VALUE 如果整数是最小位 会发生溢出 所以这么写
	int min = temp == Integer.MIN_VALUE ? temp : temp & (-temp);

而后开始进行元素划分:那两个元素和min进行与运算,一定是一个为0,一个为1(位运算均为1才为1,而min仅有一位为1,min为1的那一位是两个元素异或为1的最低位,即两个元素不相等,所以与运算所得的值也是为0、为1,所以可以据此进行划分)
再用两个从0开始的数对这两个分类分别进行异或运算,因为相同的元素肯定会被分到同一个组,进行异或运算后会消除,最后每个组都只剩下那个唯一的数。

       int num1 = 0;
       int num2 = 0;
       for (int i = 0; i < nums.length; i++) {
           //为1的那位不同的那一组(即min那一位为1 这一组数字的那一位都为0)
           if ((min & nums[i]) == 0) {
               num1 ^= nums[i];
           } else {//相同的那一组
               num2 ^= nums[i];
           }
       }

整体代码展示

public class Test3CSDN {
    public static void main(String[] args) {
        int[] nums = {12, 34, 21, 34, 12, 22, 6, 18, 21, 6, 22, 17};
        //首先找到在数组中不重复出现的那两个数字,求它俩的异或值
        int temp = 0;
        for (int i = 0; i < nums.length; i++) {
            temp ^= nums[i];
        }
        //将二者的异或值与其负数进行与运算,可得二者出现1的最低位
        int min = temp & (-temp);
        int num1 = 0;
        int num2 = 0;
        for (int i = 0; i < nums.length; i++) {
            //进行分组 根据min的那一位1进行划分
            if ((min & nums[i]) == 0) {
                num1 ^= nums[i];
            }else {
                num2 ^= nums[i];
            }
        }
        System.out.println("仅出现一次的两个元素为:" + num1 + "," + num2);
    }
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值