【剑指offer】面试题40:数组中只出现一次的数字

本文介绍了一种使用异或操作解决整型数组中寻找两个唯一数字的方法。通过将所有数字进行异或得到初始值,并找到该值中第一个不为0的比特位,以此将数组分为两组。每组分别进行异或操作即可找到两个唯一的数字。

题目:

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

思路:

因为只有两个只出现一次的数字,所以所有数字进行异或之后得到值res一定不是0.这样,res中其中至少1bit不是0,我们根据这个bit是否为0把数组分为两组,两个只出现一次的数字肯定在不同的组。其他出现两次的数组两个肯定在相同组,而两个相同的数组异或之后是0,任意一个数字与0异或还是该数字本身。

代码:

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        if(data.size()<=1)  return;
        
        int res=data[0];
        for(int i=1;i<data.size();++i)
            res=res^data[i];
        
        int k=find1Index(res);
        
        *num1=0;
        *num2=0;
        for(int i=0;i<data.size();++i)
        {
            if(kBitIs1(data[i],k))
                *num1=(*num1)^data[i];
            else
                *num2=(*num2)^data[i];
        }
        
    }
private:
    bool kBitIs1(int num, int k)
    {
        return ((num>>k)&1)!=0;
    }
    
    int find1Index(int num)
    {//找最右边的1的位数
        int k=-1;
        while(num)
        {
            ++k;
            if(num&1)
            {
                //++k;这句应该不管if-else都要执行才对
                return k;
            }
            else
                num=num>>1;//不能只写成num>>1;
        }
        return k;
    }
};

 

转载于:https://www.cnblogs.com/buxizhizhou/p/4764780.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值