数组中只出现一次的数字

数组中只出现一次的数字

题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。

异或操作找数字, 学习了, 另外注意一下num << 1左移一位, num数字本身并不改变, num = num << 1此时num数字才被改变, 这坑跳了好多次了

思路: 当一个数字中除了一个数字出现一次外, 其他数字全部出现偶数次, 则把这个数组进行异或操作, 偶数次的数字异或全部为0, 剩下的则为那个出现一次的数字

同理, 当有两个出现一次的数字时, 异或的结果肯定有一位是1(否则就相同的), 通过这个位把数组区分为两个数组, 则可以把这两个不同数字划归到不同数组中, 剩下操作同上

class Solution {
public:
    
    unsigned int findFirstBitIs1(int num) {
        unsigned int counts = 0;
        //while (1 != (num & 1)) {
        while (((num & 1) == 0) && (num < 8 * sizeof(int))) {
            counts++;
            num = num >> 1;
        }
        return counts;
    }
    bool isBit1(int num, unsigned int index) {
        num = num >> index;
        return (num&1);
    }
    
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        if (data.empty() || data.size() < 2) 
            return;
        
        // 数组异或的结果
        int res = 0;
        for (int i = 0; i < data.size(); i++) {
            res ^= data[i];
        }
        
        unsigned int firstBitIs1 = findFirstBitIs1(res);
        
        *num1 = *num2 = 0;
        for (int i = 0; i < data.size(); i++) {
            if (isBit1(data[i], firstBitIs1)) {
                *num1 ^= data[i];
            }
            else {
                *num2 ^= data[i];
            }
        }
        
        return;
    }
};

利用STL库map建立映射, 没什么好说的

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        map<int, int> my_Map;
        vector<int> vt;
        
        for (int i = 0; i < data.size(); i++) {
            my_Map[data[i]]++;
        }
        for (int i = 0; i < data.size(); i++) {
            if (my_Map[data[i]] == 1) {
                vt.push_back(data[i]);
            }
        }
        *num1 = vt[0];
        *num2 = vt[1];
        return;
    }
};
posted @ 2019-03-09 11:57  张飘扬  阅读(134)  评论(0编辑  收藏  举报