如何快速找出一个数组中只出现一次的两个数,其他元素出现两次?保证时间复杂度O(n),空间复杂度O(1)
分析步骤:
1、对数组中所有元素求异或,得到结果result。那么由于这个数组中有两个数只出现一次,而其他元素出现两次,所以result的结果一定不为零
2、找出result中任意不为零的位,保存位的下标,记作index
3、将数组分为第index位为零和不为零两组,分别对这两组进行异或运算,即可得到数组中只出现一次的两个数
java代码如下:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(input.hasNext()) {
String[] str = input.nextLine().split(" ");
int[] arr = new int[str.length];
for (int i = 0; i < str.length; i++) {
arr[i] = Integer.parseInt(str[i]);
}
int result[] = getOnceElements(arr);
System.out.println(Arrays.toString(result));
}
}
public static int[] getOnceElements(int[] arr) {
//用于保存结果
int[] result = new int[2];
//1、先进行异或,得到数组中所有元素异或的结果
int res = arr[0];
for (int i = 1; i < arr.length; i++) {
res ^= arr[i];
}
//2、找到异或结果二进制表示中中不为0的位
int index = 0;
for (int i = 0; i < 32; i++) {
if ((res >> i & 1) == 1) {
index = i;
break;
}
}
//3、将数组按第index位为0和为1,分为两组
for (int i = 0; i < arr.length; i++) {
if ((arr[i] >> index & 1) == 1) {
result[0] ^= arr[i];
} else {
result[1] ^= arr[i];
}
}
return result;
}
}
测试结果:
1 2 1 2 4 3 5 5
[3, 4]
3 4 5 6 3 4 7 8 5 6
[7, 8]