数组中只出现一次的数字C++

描述:

在这里插入图片描述

思路:

原题解读;
一定有两个数字是我们所求,我们不用担心,给定数字的长度一定等于2+2N

思路分析:
任何两个相同的数字进行异或都会得到零
可以推出给定数组进行异或会得到一个值等于 所求两数进行异或

1^1 = 0
0^0 = 0
1^0 = 1
0^0 = 0
可以推出这两个所求数字进行异或得到的 数字二进制中一定有一个1

如何确定一的位置:
a&b 只有1和1才是1,其余为零

代码步骤:
对给定数组中的数字全部进行异或得到 (两个所求数字进行异或的值)–》a
找到a二进制的第一个1的位置–》b
将给定数组进行分类b位置有1 的,b位置是零的
两个分类中的所有数字进行异或的到我们所求

代码:

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        if(num1 == nullptr || num2 == nullptr) return;
        
        //1.整体异或
        int result = data[0];
        for(auto it = data.begin()+1;it != data.end();it++)
            result^=*it;
        
        //2.找到第一个1的位置
        int flag = 1;
        int length = sizeof(int);//数字在计算机中一共是32位存储的
        for(int i = 0;i<length;i++)
        {
            if((flag << i) & result)
            {
                flag <<= i;
                break;
            }    
        }
        
        //3.分组异或
        *num1 = 0;
        *num2 = 0;
        for(int i = 0;i<data.size();i++)
        {
            if(data[i] & flag)
                *num1 ^= data[i];
            else
                *num2 ^= data[i];
        }
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值