题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素出现两次。找出只出现一次的元素。
示例
输入: [2,2,3] 输出: 3
思想
使用按位异或。异或:如果a、b两个值不相同,则异或结果为1。 如果a、b两个值相同,异或结果为0。
public static void main(String[] args) {
int a [] = new int []{2,2,3};
int temp = 0;
for (int i = 0; i < a.length; i++) {
temp ^= a[i];
}
System.out.println(temp);
}
加强
上述数组中有两个数出现一次,求这两个数。
示例
输入: [2, 2, 6, 4, 5, 5] 输出: 4, 6
思想
先将所有数按位异或,得到temp,找到temp中二进制位为1的下标,通过这个下标将所用数分为两个数组,分别异或可以得到两个值。
若有两个数都只出现了一次,若将所有数进行按位异或后,所得到的数中,若按照上述划分,必然可以将这两个数分到不同的数组中
代码
public static void main(String[] args) {
int a [] = new int []{2, 2, 6, 4, 5, 5};
int temp = 0;
int max = 0;
for (int i = 0; i < a.length; i++) {
temp ^= a[i];
if (max < a[i]) {
max = a[i];
}
}
int maxLength = Integer.toBinaryString(max).length();
String tempString = Integer.toBinaryString(temp);
StringBuilder sb = new StringBuilder(maxLength);
for (int i = 0; i < maxLength-tempString.length(); i++) {
sb.append("0");
}
sb.append(tempString);
int index = sb.length() - 1;
for (; index >= 0; index--) {
if(sb.charAt(index) == '1') {
break;
}
}
int temp1 = 0;
int temp2 = 0;
for (int i = 0; i < a.length; i++) {
String aiBinary = Integer.toBinaryString(a[i]);
if(aiBinary.length()>index && aiBinary.charAt(aiBinary.length()-index-1) == '1') {
temp1 ^= a[i];
} else {
temp2 ^= a[i];
}
}
System.out.print(temp1 + ", " + temp2);
}