面试题1. 数组中只有一种数字出现过奇数次,其他都是偶数次,打印这个数
public static void main(String[] args) {
// 数组中只有一种数字出现过奇数次,其他都是偶数次,打印这个数
int [] nums = {1,2,3,4,3,2,1};
process(nums);
}
private static void process(int[] nums) {
int eor = 0;
for(int i=0;i<nums.length;i++) {
eor^=nums[i];
}
System.out.println(eor);
}
面试题2 . 数组中有两个不同的数出现了奇数次,其他的数出现了偶数次,请找出这两个数.
public static void main(String[] args) {
// 数组中只有2数字出现过奇数次,其他都是偶数次,打印这个数
int [] nums = {1,2,3,4,3,2,1,5,5,2};
int eor = 0;
for(int i=0;i<nums.length;i++) {
// 异或完后,eor就等于那2个出现过奇数次的数字
eor^=nums[i];
}
// 找到最右侧的1
int rightOne = eor& (~eor+1);
int a = 0;
for(int i = 0 ;i<nums.length;i++) {
if((rightOne&nums[i])!=0) { // 说明nums[i] 最右侧有1
a^=nums[i];
}
}
int b = eor^a;
System.out.println(a+","+b);
}
要点:提取最右侧的1
// 提取最右的1
// N = 100010110000
// ~N = 011101001111
// (~N+1) = 011101010000
// N&(~N+1)= 000000010000