找出数组中只出现一次的数

这个题目有三种变形。

第一种,一个数组中所有数都出现了两次,只有一个数出现了一次,求这个数。这个题比较简单,只要知道数字间异或的特性,就可以很容易的得出答案。

int find_num_appear_once(int *data, int length){
    if(data==NULL || length==0)return;
    int i=0;
    int res=0;
    for(;i<length;i++){
        res ^= data[i];
    }
    return res;
}

第二种,一个数组中所有的数都出现两次,只有两个数出现了一次,求出这两个数。这个题目比较难,需要把未知问题向已知问题转化。先把所有数全部异或,得到一个数,这个数是答案中两个数异或的结果所以它一定不为0,那么把它转化为二进制数的时候一定有一位位1。通过这个数的二进制数中第一个为1的那一位将数组中的数分成两部分,那么这两部分就是问题一里的情况了,分别再用问题一的方法把答案找出来。

int *find_num_appear_once(int *data, int length){
    if(data==NULL || length<2)return;
    int i=0;
    int j=0;
    int temp=0;
    int res[2]={0};
    for(;i<length;i++){
        temp ^= data[i];
    }
    unsigned int index=find_first_index(res);
    for(;j<length;j++){
        if(is_bit_one(index, data[j])){
            res[0] ^= data[j];
        }else{
            res[1] ^= data[j];
        }
    }
    return res;
}

unsigned int find_first_index(int num){//找到第一个为1的位
    int index_bit=0;
    while((num&1)==0 && index_bit<32){
        num>>1;
        index_bit++;
    }
    return index_bit;
}

bool is_bit_one(unsigned int num1, int num2){//判断一个数的num1位是否为1
    int num = num2>>num1;
    return (num&1);
}

第三种,一个数组中所有的数都出现过三次,只有一个数出现过一次,求这个数。这个题目的解决办法是通过将这个数组中数字的每一位相加再与3取余数,这样这个余数不是1就是0。再将这个余数放置到相应位上(是通过数组中数的第几位得到的余数就放在第几位),这样就可以重组出那个单一的数。

int *find_num_appear_once(int *data, int length){
    if(data==NULL || length==0)return;
    int i=0;
    int j=0;
    int res=0;
    int num=0;
    for(;i<32;i++){
        num=0;
        for(j=0;j<length;j++){
            num += (data[j]>>i)&1;//循环完成,num存储了在这个位上一共有多少个1
        }
        res |= (num%3)<<i;
    }
    return res;
}

 

转载于:https://www.cnblogs.com/focus1987/p/3975526.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值