链接:https://www.nowcoder.com/questionTerminal/e02fdb54d7524710a7d664d082bb7811
来源:牛客网
题目中,数组中的数字是除了特殊的两个外,都出现了两次,因此,异或法是一个很好的选择;
所谓异或:
两个相同数字异或=0,一个数和0异或还是它本身。
当只有一个数出现一次时,我们把数组中所有的数,依次异或运算,最后剩下的就是落单的数,因为成对儿出现的都抵消了。
按照这个思路来找题中的数组(即两个只出现一次的数);
public class testtest {
public static void main(String[] args){
int bitResult = 0;
int[] array = new int[]{6,5,3,3};
int length = array.length;
for(int i = 0; i < length; ++i){
bitResult ^= array[i];
}
System.out.println(bitResult);
}
}
如上代码所示,这个代码中bitResult为数组中各个数依次异或后的结果,其中3和3抵消了,而6的二进制是110; 5的二进制为101;两个异或结果为011,返回3;那么这个异或结果中的1其实就是6和5中不同的位,不妨取第一个1的位置,即二进制结果中的第1位,【6,5,3,3】=[110,101,11,11],可以按照第一位分为两组[6],[5,3,3];相同的数肯定在一个组,因为相同数字所有位都相同,而不同的数,肯定不在一组。【5,3,3】自然也可以分为[5]和[3,3]两组;
public class testtest {
public static void main(String[] args){
int index = 0;
int bitResult = 6;
while(((bitResult & 1) == 0) && index < 32){
bitResult >>= 1;
index++;
}
System.out.println(index);
}
}
这段代码,目的是找出第一个1所在的位置;那么开始分组,将数字按照在上述代码得出的index位置上是否为1进行分组;
public class testtest {
public static void main(String[] args){
int target = 5;
int index = 3;
System.out.println(((target >> index) & 1) == 1);
}
}
整体代码如下:
public class Test {
public static void FindNumsAppearOnce(int[] array, int[] num1, int[] num2) {
int length = array.length;
if(length == 2){
num1[0] = array[0];
num2[0] = array[1];
return;
}
int bitResult = 0;
for(int i = 0; i < length; ++i){
bitResult ^= array[i];
}
int index = findFirst1(bitResult);
for(int i = 0; i < length; ++i){
if(isBit1(array[i], index)){
num1[0] ^= array[i];
}else{
num2[0] ^= array[i];
}
}
}
public static int findFirst1(int bitResult){
int index = 0;
while(((bitResult & 1) == 0) && index < 32){
bitResult >>= 1;
index++;
}
return index;
}
public static boolean isBit1(int target, int index){
return ((target >> index) & 1) == 1;
}
public static void main(String[] args){
int[] Array = new int[]{1,1,3,5};
int length = Array.length;
int[] nums1 = new int[length];
int[] nums2 = new int[length];
FindNumsAppearOnce(Array,nums1,nums2);
System.out.println(nums1[0]);
System.out.println(nums2[0]);
}
}