无进位相加
00111
01101
得 01010
性质:
- 0^N = N
- N^N =0
- a ^ b ^ c =abc位置可以随意
第一题
不用额外变量交换 两个数,请保证两个数的内存地址是不一样的
public static void swap(int i,int j){
i = i ^ j;
j = i ^ j ;
i = i ^ j;
}
第二题
一种数出现奇数次,其他都出现偶数次,找出这个数
public static int getOneOdd(int[] arr){
int ans = 0;
for (int i : arr) {
ans ^= i;
}
return ans;
}
第三题
两种数出现奇数次,其他数都出现偶数次,请找出奇数次的两种数
public static int[] getTwoOdd(int[] arr){
int[] result = new int[2];
int ans1 = 0;
int ans2 = 0;
int eor = 0;//ans1 ^ ans2
for (int i : arr) {
eor ^= i;
}
//找到eor最右侧的1
int rightOne = eor & (-eor);
for (int i : arr) {
if((i & rightOne) !=0){
ans1 ^= i;
}
}
ans2 = eor ^ ans1;
result[0] = ans1;
result[1] = ans2;
return result;
}
第四题
一个数组中有一种数出现K次,其他数都出现M次,M>1,K<M.
找到出现了K次的数。要求,额外空间复杂度O(1),时间复杂度O(n)
public static int getK(int[] arr,int k,int m){
int[] help = new int[32];
int result = 0;
for (int val : arr) {
for (int i = 0; i <= 31; i++) {
// if( (val >> i & 1) == 1){
// help[i]++;
// }
//优化
help[i] += (val>>i) & 1;
}
}
//处理help数组
for (int i = 0; i <= 31; i++) {
if(help[i] % m !=0){
result |= (1 << i);
}
}
return result;
}