剑指offer-数组中只出现一次的数字

本文介绍了一种利用位操作解决寻找数组中仅出现一次的两个数字的问题。通过整体异或计算并找到不同位,将数组分成两组,分别进行异或运算得到目标数字。

题目描述:

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

解题分析:

  1. 位算法中,相同的数字经过异或运算为0。

  2. 现在数组中有两个数字只出现1次,直接异或一次只能得到这两个数字的异或结果,但光从这个结果肯定无法得到这个两个数字。因此我们来分析下简化版中“异或”解法的关键点,这个关键点也相当明显——数组只能有一个数字出现1次。

  3. 设题目中这两个只出现1次的数字分别为A和B,如果能将A,B分开到二个数组中,那显然符合“异或”解法的关键点了。因此这个题目的关键点就是将A,B分开到二个数组中。由于A,B肯定是不相等的,因此在二进制上必定有一位是不同的。根据这一位是0还是1可以将A,B分开到A组和B组。而这个数组中其它数字要么就属于A组,要么就属于B组。再对A组和B组分别执行“异或”解法就可以得到A,B了。而要判断A,B在哪一位上不相同,只要根据A异或B的结果就可以知道了,这个结果在二进制上为1的位都说明A,B在这一位上是不相同的。

public static void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        // 1.整体异或,计算结果
        int differ = 0;
        for(int i : array) {
            differ^=i;
        }
        // 2.找到第一个为1的位置
        int j=0;
        for(j=0; j<32; j++){
            if(((differ>>j)&1)==1){
                break;
            }
        }
        // 3.将第j为为1的和不为1的分为两组
        int length = array.length;
        int[] array1 = new int[length];
        int[] array2 = new int[length];
        for(int k=0,k1=0,k2=0;k<length;k++){
            if(((array[k]>>j)&1)==0){
                array1[k1++]=array[k];
            }
            else{
                array2[k2++]=array[k];
            }
        }

        //分别得出两个数
        for(int i : array1) {
            num1[0]^=i;
        }
        for(int i : array2) {
            num2[0]^=i;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值