leetcode-260-SingleNumber III

问题

题目:[leetcode-260]

思路

可参考这个链接[数组中只出现1次的两个数字(百度面试题)]。下面是我自己的总结:

首先,对于只有一个不同的数字的情形。xor可以解决。但是对于本题,由于出现两个只出现一次的数字。所以,xor的结果是最后这两个数字的xor结果。所以,直接这么做不可以。

不妨这么考虑,由于a和b是出现在同一个数组中。所以没法分开,如果把它们分到不同的数组中,对于这两个不同的数组而言。a和b是可以分别找到的。由于a不等于b,所以它们两的位向量中必然有一位不同。假设第 ci 不同,可以利用第 ci 位与a和b相与的结果把a,b分开。同理,用 ci 位把数组中剩余的数也分开。这样对于这两个数组,分别做xor即可得到这两个数字。

大体流程如下:

  • 把数组分别为各自包含a,b的两个子数组
  • 对这两个子数组求xor分别获得a,b

第一个是核心,怎么划分开。上面说道,利用a和b位向量当中不同的那一位 ci 当做mask。把数组划分开即可。问题是怎么得到mask。mask是位向量当中不同的那一位,那么a^b的结果当中位向量为1的就是二者不同的位。而a^b的结果刚好可以通过对数组xor来得到。

代码

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {

        vector<int> v1;
        vector<int> v2;
        vector<int> res;


        int sz = nums.size();
        int ret = 0; // a^b
        for( int i = 0; i < sz; ++i ){
            ret ^= nums[i];
        }

        // debug
        //std::cout << "ret=" << ret << std::endl;

        int mask = 1;
        while( !(ret&mask) )
        {
            mask <<= 1;
        }

        // debug
        //std::cout << "mask=" << mask << std::endl;

        for( int i = 0; i < sz; ++i ){
            if( nums[i] & mask )    
                v1.push_back(nums[i]);
            else
                v2.push_back( nums[i] );
        }

        int ans1 = singleNumberOne(v1);
        int ans2 = singleNumberOne(v2);

        res.push_back(ans1);
        res.push_back(ans2);

        return res;
    }
private:
    int singleNumberOne( vector<int>& nums ){
        int sz = nums.size();
        int ret = 0;
        for( int i = 0; i < sz; ++i ){
            ret ^= nums[i];
        }
        return ret;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值