剑指offer-数组中只出现一次的数字

问题

题目:[剑指offer-数组中只出现一次的数字]

思路

这个题朴素的思路就不说了,哈希即可。
说下位运算的思路,其实我不会做,参照了别人的做法。
大体思路如下:
1. 可以采用^操作,可以消除一样的数字。但是,这回导致一个问题,最后的结果是num1和num2亦或的结果。
2. 这是本题的精髓,考虑到如果有两个数字不能分开,但是如果一个数组中其余数字两两相同,只有一个数组不同,可以用上述的办法。我们着手考虑把这两个不同的数字分配到不同的数组当中即可。因为num1 != num2,所以num1 ^ num2的结果必然不为0,那么我们只需找出这两个数字在哪一位是不相同的,然后用这个MASK和所有数字^,这样自然可以把所有数字分配到两个不同的数组中。

代码

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {

        int sz = data.size();
        if(!sz) return;

        int ans = 0;
        for(int i = 0; i < sz; ++i){
            ans ^= data[i];
        }

        std::bitset<32> bitarr(ans);
        int mask = 1;
        for(int i = 0; i < 32; ++i){
            if( bitarr[i] ) break;
            else mask <<= 1;
        }

        vector<int> arr1;
        vector<int> arr2;

        for(int i = 0; i < sz; ++i){
            if( data[i] & mask ) arr1.push_back( data[i] );
            else arr2.push_back( data[i] );
        }

        int sz1 = arr1.size();
        ans = 0;
        for(int i = 0; i < sz1; ++i){
            ans ^= arr1[i];
        }
        num1[0] = ans;

        int sz2 = arr2.size();
        ans = 0;
        for(int i = 0; i < sz2; ++i){
            ans ^= arr2[i];
        }
        num2[0] = ans;

        return;
    }
};

代码1

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {

        int sz = data.size();
        if(!sz) return;

        int ans = 0;
        for(int i = 0; i < sz; ++i){
            ans ^= data[i];
        }


        int mask = 1;
        for(int i = 0; i < 32; ++i){
            if( ans & mask ) break;
            else{
                mask <<= 1;
            }
        }

        vector<int> arr1;
        vector<int> arr2;

        for(int i = 0; i < sz; ++i){
            if( data[i] & mask ) arr1.push_back( data[i] );
            else arr2.push_back( data[i] );
        }

        int sz1 = arr1.size();
        ans = 0;
        for(int i = 0; i < sz1; ++i){
            ans ^= arr1[i];
        }
        num1[0] = ans;

        int sz2 = arr2.size();
        ans = 0;
        for(int i = 0; i < sz2; ++i){
            ans ^= arr2[i];
        }
        num2[0] = ans;

        return;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值