【剑指offer】数组中找两个不重复数字

问题描述数组中除了两个数之外,其他数都出现两次,找出数组中两个只出现一次的数字。

解题思路:首先可以思考这样的情况,两个相同的数字进行异或,异或的结果等于0。所以我们可以以此作为解题的突破口。如果只有一个数字的话,那么我们让所有的数字分别进行异或,最终得到的结果就是这个只出现一次的数,然后定义一个指针带出数据即可。
   可是问题是有两个数据,我们通过异或每一次只能筛选一个数字,是不是可以通过怎样的方法将两个数字进行分组呢,这样每一组只出现一个数字,可以分别对两组数据进行异或处理即可得到只出现一次的数。将两个数据分开前提是我们要知道两个数字不同,先拿到所有数字异或的结果,然后找到 最低位是1的数字,你可能要问了:为什么找最低位是1的数字呢?因为所有的数字进行异或得到的结果,其实等于这两个不相等数据的异或结果。所以哪一位是1说明这一位有一个数据是1,一个数据为0.以此进行划分。
     划分之后的两组数据,我们对两组数据再进行异或处理 ,最终得到的就是我们想要的结果了。
代码实现如下:
class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        int size=data.size();
        if(size<2)
        {
            return;
        }
        int tmp=0;
        for(int i=0;i<size;i++)
        {
            tmp^=data[i];
        }
        int index=findindex(tmp);
        for(int i=0;i<size;i++)
        {
            if(IsBit(data[i],index))//
            {
                num1[0]^=data[i];
            }
            else{
                num2[0]^=data[i];
            }
        }
    }
    int findindex(int num)
    {
        int count=0;
        while((num&1)==0)
        {
            num=num>>1;
            count++;
        }
        return count;
    }
    bool IsBit(int num,int count)
    {
        num=num>>count;
        return (num&1)==1;
    }
  };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值