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

  • 题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
  • 思路分析
    首先分析如果数组中只有一个数字只出现一次,在这个时候,我们可以利用一个数异或它本身等于0这个特性,从头异或至尾即可获得只出现了一次的数(此时直接在循环中进行与运算即可)。那么有两个出现一次的数时,我们可以将这个数组分成两部分,每一部分都包含一个只出现一次的数区分的方法
    将数组中所有元素异或获得一个数设为r1,那么由于出现两次的数都被异或抵消了,r1的结果就是两个只出现了一次的数异或的结果,设这两个数为num1,num2,即num1^num2=r1,然后寻找r1中第一个为1的位的位置,设为index,则num1和num2的index位一定一个为0一个为1,根据这个方法可以将数组分成两个部分。查找第一个1位时,可以将r1与1进行与运算,如果为0则右移一位,知道与运算结果为1.index位的0、1判断可以直接右移index位,进行与运算。

  • 代码
bool IsBit(int num ,int index){
        num=num>>index;
        return num&1;
    }
    void FindNumsAppearOnce(vector<int> data,int *num1,int *num2) {
       int size=data.size();

        int r1;
        for(int i=0;i<size;i++){
            r1 ^= data[i];
        }

        int index=0;
        while((r1&1) == 0){
            index++;
            r1=r1 >> 1;
        }
        *num1=0;*num2=0;
        for(int i=0;i<size;i++){
            if(IsBit(data[i],index)){
                *num1^=data[i];
            }
            else{

                *num2^=data[i];
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值