数组中只出现一次的数字

来源:互联网 发布:南望王师又一年 知乎 编辑:程序博客网 时间:2024/06/06 04:44

一、一个数组中有一个数字出现了一次,其余的数字都出现了两次。快速找出只出现一次的那个数字。

思路:位运算中两个相同的数按位异或结果是0,另外0与任何数异或结果就是那个数。因此将数组中所有的元素一起做异或运算,出现两次的元素会消掉,最后只剩那个只出现一次的数字。

二、一个数组中有两个数字出现了一次,其余的数字都出现了两次。快速找出只出现一次的那两个数字。

例如:1,1,2,2,3,3,8,9
借鉴第一个问题的思路,如果能先把数组分成两部分,一部分含有一个目标数字,那接下来就能使用第一个问题的解决方法了。将所有元素做异或运算就相当于两个目标数字做异或运算。两个目标数字不相等,异或之后结果肯定不是0,那么异或的结果某一位为1的话,两个目标元素的这一位肯定不同。这样根据这一位是否为1就可以把原始数组分成两部分。再按照第一题的思路解决。
代码如下:

class Solution {public:    int Just1NumAppearOnce(vector<int>& data){//只有一个数字出现了一次。        int len = data.size();        if(len <= 0)            return -1;        int ans = data.at(0);        for(int i = 1; i < len; i++)            ans ^= data.at(i);        return ans;    }    int findBit1(int n){//找出哪一位为1        int x = 1;        for(int i = 0; i < 32; i++){            if((x & n) != 0)                return i;            else                x = x << 1;        }        return -1;    }    bool isXBit1(int n, int index){//第index位是否为1        int x = 1;        for(int i = 0; i < index; i++)            x = x << 1;        if((n & x) == 0)            return false;        else            return true;    }    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {        *num1 = 0;        *num2 = 0;        int len = data.size();        if(len < 2)            return;        int exclu = data.at(0);        for(int i = 1; i < len; i++)            exclu ^= data.at(i);        int index = findBit1(exclu);        vector<int> data0;        vector<int> data1;        for(int x : data){            if(isXBit1(x, index))                data1.push_back(x);            else                data0.push_back(x);        }        *num1 = Just1NumAppearOnce(data0);        *num2 = Just1NumAppearOnce(data1);    }};
0 0
原创粉丝点击