🙇异或的性质
1、a^a=0 任何数字和自己异或结果是0
2、a^0=a 任何数字和0异或还是他自己
3、a^ b = b ^ a 异或运算具有交换律
4、a ^(b ^ c) = (a ^ c) ^ b 异或运算具有结合律
注意 1、两个数异或又叫不进位相加
2、异或在两个数字交换中的应用
a = a ^ b;
b = a ^ b;
a = a ^ b;
这样做的优点在交换过程中没有使用额外的内存空间
缺点是这种情况并不能适用于所有的情况如果两个要使用交换的两个数字内存地址一致时,会将这两个交换的数字都置换为0
Leetcode 136
class Solution {
public int singleNumber(int[] nums) {
int i = 0;
for(int j = 0; j < nums.length; j++){
i^= nums[j];
}
return i;
}
}
在本题中就是利用了异或的 N ^ N = 0 的性质 ,将数组中的全部元素异或起来所有出现两次的元素都变为 0 了,0 在与出现一次的元素异或还是那个元素,
Leetcode 260
class Solution {
public int[] singleNumber(int[] nums) {
int ans = 0;
for(int i : nums){
ans^= i; //现在的ans = a ^ b; a和b分别代表数组中那两个只出现一次的元素
}
int right = ans & (~ ans +1); // 提取出最右侧的1
int only = 0;
for(int i: nums){
if((i & right) == 0){ //找出最右侧1的位置为0的数并且异或起来,求出其中的一个数 这里最后等于0或等于1都可以
only^= i; // 算出其中的一个元素
}
}
int only2 = only^ans; //将其中的一个数异或 上面求出的 a ^ b
return new int[]{only, only2};
}
}
int right = ans & (~ ans +1);
将图中两个前面带方框的数&(与)起来后就可得到a, 即提出最右侧的1并赋值给a;
返回数组的方法
通过在return后new一个新的数组进行放回在题中求出的数字(例:return new int[]{only, only2};),或者之间返回一个数组名。