介绍
异或(^)是指按位异或,即二进制中每位有:0^0=0,0^1=1,1^1=1,也就是0与a异或得起a本身。
异或使用例子1
通过使用异或可以将两个数值进行交换,同时不使用额外的变量。
即
a^=b;
b^=a;
a^=b;
使用以上代码块就可以将a、b相交换。
代码
template <typename T>
void swap(T &a, T &b){
a^=b;
b^=a;
a^=b;
}
异或使用例子2
若a=0,b为任意数时:
m=a^b(m为中间值);
m=m^b;
则最后一次的m即为a。
因为a与b异或后得到一个中间值,该中间值再一次和b异或就会将最开始a与b异或后a每位发生的变换复原,即0^0=0,0^1=1,1^1=1。
题目
136. 只出现一次的数字https://leetcode.cn/problems/single-number/
给你一个 非空 整数数组
nums
,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
代码
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res=0;
for(auto num:nums){
/*
*由于与0相异或得本身,
*且异或同一值两次得最开始与重复值相异或的值的原则,
*只要有一个为单值,
*则必为正确结果。
*a^=b得a=c,b^=a得b=a,a^=b得a=b
*即a与b异或得到一个中间值,
*b与中间值异或得到a,
*即回到最开始的a
*/
res ^=num;
}
return res;
}
};
解析
由于与0相异或得本身,且异或同一值两次得最开始与重复值相异或的值的原则,只要有一个为单值,则必为正确结果。
即a与b异或得到一个中间值,b与中间值异或得到a,即回到最开始的a。也就是说,利用对nums数组的遍历,将res与数组每一位都异或,最后res留下的只会是单个存在的,意味着双个存在的都会在最后一次与该值异或时复原成没异或之前的值。
而将res=0,是由于0与任何数异或都为该数,故而实现代码的统一性。