只出现一次的数字III(自用)

leetcode:260. 只出现一次的数字 III

题目要求:只有两个数出现过一次,其他数字都出现两次抓住题目

要领:其他数出现了两次

所以第一步应该异或^那是不是就只剩下了要找的那两个数的异或值,因为两个相同的数异或就变成了0

,0和任何数 ^ 异或就还是本身

如何把两个数的异或值分开

比如上面的example:5:0000 0101

                                    3:  0000 0011

                                 5^3: 0000 0110

有没有发现当出现1时就证明:这个1可能是5的或着是3的

所以在第一次出现1的位置5和3有一个是1有一个是0  可以搞个两个集合就是这个位置是1 or  0  

但是在整个数组里面有可能有其他数也是1但是不影响因为它们是出现两次的所以^异或就可以了

那我们就可以找到唯一区分5和3的标识,比如第1个位置(数组)也可以第2 也可以唯一标识区分

所以我可以把5和3的异或的值第一个出现1的二进制作为标识去区分要我们找vector<int>nums 的值中只出现一次的两个数字

如何去找呢?

观察一下我们可以遍历32位的   5^3: 0000 0110  然后找到1的下标 用A &1<<i

就可以找到下标

知道下标就可以取数了

整体代码

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) 
    {
        int a =0;
        for(auto e:nums)
        {
            a^=e;
        }
        int i =0;
        while(i<32)
        {
            if(a&(1<<i))
            {
                break;
            }
            i++;
        }
        int num1=0;
        int num2=0;
        for(auto e:nums)
        {
            if(e&(1<<i))
            {
              num1^=e;
            }else
            {
                num2^=e;
            }
        }
      vector<int> it;
      it.push_back(num1);
       it.push_back(num2);
       return it;

    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值