面试题:异或经典思维题目

题目:

已知数组中数字两两相同,有两个不同,找出这两个不相同的数字

解答过程:

如果数组中只有一个数字的话,那么我们就可以直接异或就OK了,但是现在有两个的话就会有点麻烦了,所以就有一个非常精彩的思想。
首先我们将所有的数字进行异或,结果肯定不会为 0 所以我们将其进行位运算的话一定会有第 index 位是 1, 所以我们将其分为两组,一组是第 index 位是 1 的数,另一组是第 index 位是 0的数,而这两组数中,那两个不同的数字一定是分开的,所以我们将这两组数字分别进行异或就找出来了。

My Code:

#include <iostream>
#include <string>

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 1e6+5;
int a[MAXN];
int main()
{
    int n;
    while(cin>>n){
        for(int i=0; i<n; i++)
            cin>>a[i];
        if(n & 1)
            return 0;
        int sum = 0, index = 0;///index判断是从右边判断第index位为 1
        for(int i=0; i<n; i++)
            sum = sum ^ a[i];
        while(1){
            if(sum & 1)
                break;
            index++;
            sum>>=1;
        }
        int num1 = 0, num2 = 0;
        for(int i=0; i<n; i++){
            if((a[i]>>index) & 1)///第 index 位是 1 的
                num1 ^= a[i];
            else                 ///第 index 位是 0 的
                num2 ^= a[i];
        }
        cout<<num1<<" "<<num2<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值