数组中单独出现的两个数

数组中有若干个数,有两个数只出现一次,其余的数都出现了两次,求出这两个单独出现的数。

leetcode260

假设两个数分别为a和b,思路就是先每个异或,然后得出a和b相异的位,结果为ans

然后取出ans最后为1的位,把原来的数组分开,再异或一次,得到答案。

这里取ans最后一位1的操作很巧妙:

ans = ans & (-ans)

假设一个数ans为xxxxxxx10000,需要返回的是000000010000。

先将ans取相反数,按照补码的操作,xxxxxx10000 -> XXXXXX01111-> XXXXXX10000

大写X表示和原来x都是相反的位。所以得到00000010000

 

另外,c++中输出二进制需要技巧:

cout<<hex<<static_cast<unsigned int>(ans)<<endl;
cout<<oct<<static_cast<unsigned int>(ans)<<endl;
cout<<dec<<static_cast<unsigned int>(ans)<<endl;
cout<<bitset<sizeof(unsigned int) * 8>(ans)<<endl;

原题的代码如下:

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int ans = 0;
        for(int n: nums)
            ans = ans xor n;
        ans = ans & (-ans);
        int a = 0, b = 0;
        for(int n: nums)
            if(n & ans)
                a = a xor n;
            else
                b = b xor n;
        return {a, b};
    }
};

在这里补一下各种码的区别:

原码:第一位为符号位,后面的是数值

反码:正数的反码是它自己,负数的反码:对于负数的原码,第一位符号位不变,其余各位取反

补码:正数的补码是它自己,负数的原码取反码后+1,就是负数的补码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值