如何快速找出一个数组中只出现一次的两个数,其他元素出现两次?保证时间复杂度O(n),空间复杂度O(1)

来源:互联网 发布:ubuntu更换源 编辑:程序博客网 时间:2024/05/22 20:27

如何快速找出一个数组中只出现一次的两个数,其他元素出现两次?保证时间复杂度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]


阅读全文
0 0