异或运算
本质:无进位相加
100110
110011
010101
- 0异或任何数都等于自身:0^x=x
- 任何数与自身异或都等于0 :x^x=0
- 异或运算满足交换律和结合律
- 不额外申请临时变量空间,实现a=x,b=y的交换
a=a^b;
b=a^b;
a=a^b;
证明:
a=a^b: a=x ^ y ,b=y
b=a^b: a=x ^ y,b=x ^ y ^ y=x
a=a^b: a=x ^ y ^ x=y,b=x
5.一个数组,只有一个数出现了奇数次,其他都出现了偶数次,要求只用O(1)额外空间,返回这个数
void odd(const vector<int>& arr,int& ans){//用0去异或数组每个数,最后的结果就是这个频次为奇数的数
int tmp=0;
for(auto k:arr)tmp=tmp^k;
ans=tmp;
}
6.一个数组,只有两个数a,b出现了奇数次,其他都出现了偶数次,要求只用O(1)额外空间,返回这两个数
void odd(const vector<int>& arr,int& ans1,int& ans2){
int eor1=0;
for(aoto k:arr)eor1^=k;//用0异或数组每一个数,得到了a^b
//a^b!=0,则a^b肯定有至少一个二进制位为1
//我们提取出最右位1
int rightOne=eor1 & (~eor1+1);
//再次用0去异或数组中最右位1为rightOne的数,得到a
int eor2=0;
for(auto k:arr){
if(k&rightOne!=0)eor2^=k;
}
ans1=eor2;
ans2=eor1^ans1;
}