数组中只出现一次的数

题目1:一个数组中,除了某一个只出现过一次的数字外,其余数字均出现过2次,找出这个只出现了一次的数字。

思路:分析题干,发现强调了数组中数字出现的次数为1和2,则可以想到异或运算,两个相同的数字异或结果为0,相同的数异或的结果为其本身,且异或运算存在交换律和结合律,即a^b^a=b, b^a^a=b。那么利用异或运算的这些性质即可求解本题:依次将数组的每个数进行异或运算,异或的结果即为所求。


题目2:一个数组中,除了某两个只出现过一次的数字外,其余数字均出现过2次,找出这两个只出现了一次的数字。

思路:基于题目1的思路来分析第二题。可以将数组分为2组,如果这两个特殊的数刚好出现在这两个数组中,那对这两个数组分别求异或即可。现在的问题是如何进行分组?一个思路是先对原数组求异或,则得到的结果为这两个特殊数字的异或值tmp,找到tmp中第一个为1的位n,说明这两个数第n位一个为1一个为0。 按照这个思路将所有数字分组:将第n位为1和为0的数字分为两组,此时这两个特殊的数字分别出现在这两个数组中,那么对这两个数组分别进行异或计算即可得到这两个数。


下面给出第2题的代码:

void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
		if(data.size() < 2)
            return ;
        
        int tmp = 0;
        for(int i = 0; i < data.size(); i ++)  //求出所有数字的异或结果存在tmp中
            tmp ^= data[i];
        int n = 0;  //tmp第一个为1的位数
        while(tmp != 0)
        {
            if(tmp & 1)
                break;
            n ++;
            tmp = tmp >> 1;
        }
        
        *num1 = 0;
        *num2 = 0;
        
        for(int i = 0; i < data.size(); i ++)
        {
        	if((data[i] >> n) & 1)	
                *num1 = *num1 ^ data[i];  //data中第n位为1的数据与num1异或计算
            else
                *num2 = *num2 ^ data[i];
        }

    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值