题目描述
题目1:数组中只出现一次的两个数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
如,输入数组{2,4,3,6,3,2,5,3}
练习地址
实现
方法:异或
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class C56_array_FindNumsAppearOnce {
public static void appearOnce(int[] arr, int num1[], int num2[]) {
if (arr == null || arr.length < 1) {
return;
}
if (arr.length == 2) {
num1[0] = arr[0];
num2[0] = arr[1];
return;
}
int resOR = 0;
// 依次异或,最终结果为个数为1的两个数的异或结果
for (int i = 0; i < arr.length; i++) {//4^6=0010
resOR ^= arr[i];
}
int indexOf1 = findFirstBitls(resOR);//0010,倒数2个
for (int i = 0; i < arr.length; i++) {
if (isBit(arr[i], indexOf1)) {//倒数第2个是1或0,分组
num1[0] ^= arr[i];//异或后获得结果
} else {
num2[0] ^= arr[i];
}
}
}
// 获取二进制最右边数第一个是1的位
public static int findFirstBitls(int num) {
int indexBit = 0;
//num&1判断num最后1位是否为1,也用来判断奇偶性
while (((num & 1) == 0) && (indexBit < 8 * 4)) {//sizeof(int)=4
num = num >> 1;
++indexBit;
}
return indexBit;
}
//判断二进制中从右边数的indexBit是不是1
public static boolean isBit(int num, int indexBit) {
num = num >> indexBit;
return (num & 1) == 1;
}
}
Test
public static void main(String[] args) {
int[] arr={2,4,3,6,3,2,5,5};
int[] num1={0};
int[] num2={0};
appearOnce(arr,num1,num2);
System.out.println(num1[0]);
System.out.println(num2[0]);
}