c++实现---数组中只出现一次的数(两个)

题目:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
方法一:暴力法(借助哈希实现)
很显然的方法,遍历一遍数组,用map记录出现的次数,然后再遍历一遍数组,找出出现1次的数字。
代码

#include<unordered_map>
class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        unordered_map<int,int> help;
        for(const int val:data) ++help[val];
        vector<int> res;
        for(const int val:data){
            if(help[val]==1){
                res.push_back(val);
            }
        }
        *num1=res[0];
        *num2=res[1];
    }
};

时间复杂度:O(n)
空间复杂度:O(n)
方法二:位运算(优化解,面试更需要)
异或运算:如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
n^0 = n;
n^n = 0;
nnm = n(nm) 满***换律
1.我们可以让数组中的每一个数异或一下,最后会得到一个结果ret,
2.就是两个出现一次的数字的异或结果这个结果肯定是由两个不同数字异或而来,因此我们找ret二进制中为1的位置i,因为1一定是由0,1异或而来,因此要求得两个数中,一定有一个数的二进制中的第i个位置为1, 一个为0.
3.对和这个数相与为1的求异或是第一个数,为0的是第二个数
代码

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        int ret=0;
        for(const int val:data) ret^=val;//首先找到两个只出现一次数的异或
        ret &=(-ret);//找到一个是1 ,而另一个是0;两个数不相等,某一位一定是1,而在另一个数中该位是0
        *num1=0,*num2=0;
        for(const int val:data){
            if(val&ret){//对出现为1的进行异或,得到其中一个数
                *num1^=val;
            }else{//得到第二个
                *num2^=val;
            }
        }
    }
};

时间复杂度:O(n)
空间复杂度:O(1)

猜你喜欢

转载自blog.csdn.net/Fizz6018/article/details/107201709