落单的数 III

给出2*n + 2个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字。

对于2*n+1个数字用异或就行了,而在此题将所有数异或之后得到的是两个落单的数的异或结果,没办法将结果拆分成两个落单的数。但因为两个落单数不同,所以肯定存在某个位k,使得两落单数在第k位上一个为0另一个为1,怎么找到这个k? 找异或结果中1出现的位置即可。只需找到最小的这个k,然后将在k位上为0的所有数做异或,其他的在k位为1的所有数也做另外的异或,这样最终可以得到两个落单的数。

class Solution {
public:
    /**
     * @param A : An integer array
     * @return : Two integers
     */
    vector<int> singleNumberIII(vector<int> &A) {
        // write your code here
        int Xor = 0, n = A.size();
        for ( int i = 0; i < n; ++i ) Xor ^= A[i];
        int k = 0;
        while ( Xor % 2 == 0 )
        {
            ++k;
            Xor >>= 1;
        }
        int r1 = 0, r2 = 0;
        for ( int i = 0; i < n; ++i )
        {
            int kb = (A[i]>>k) % 2;
            if ( kb == 0 ) r1 ^= A[i];
            else r2 ^= A[i];
        }
        
        vector<int> res;
        res.push_back(r1);
        res.push_back(r2);
        return res;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值