【算法】寻找数组中出现的唯一重复的一个数

题目要求:

假设你有一个用1001个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1到1000(包括1000)之间。

此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。

解题思路:

数组中的1001个数相互异或的结果与(1-1000)相互异或的结果再做异或,得出的值即位所求

原理:

假设重复数为A,其余999个数相互异或结果为B。

那么1-1000异或结果为A^B;

1001个数异或结果为A^(A^B) 。

由于异或满足交换律和结合律,且X^X = 0, 0^X = X;

则有:A^(A^B)  = B ;(A^B)^B=A。

A即为所求。

代码实现:


	public static void find(int[] arr, int n){
		int result = 0;
		for(int i=0 ; i<n+1; i++){
			result ^= arr[i]; //数组内的数相互异或
		}
		for(int i=1 ; i<=n ; i++){
			result ^= i; //将上面的结果与1~n的数相互异或
		}
		System.out.println("找到重复的数为:"+result);
	}
	public static void main(String[] args){
		int[] arr = new int[10001];
		for(int i=1;i<=1000;i++){
			arr[i] = i;
		}
		int r = new Random().nextInt(1000);
		System.out.println("放入1000以内的一个随机数:"+r);
		arr[0] = r;
		find(arr,1000);

	}

将代码简化为:

	public static void find(int[] arr, int n){
		int result = 0;
		for(int i=0 ; i<n+1; i++){
			result ^= arr[i];
			result ^= i;
		}
		System.out.println("找到重复的数为:"+result);
	}

输出结果:

第1次试验
放入1000以内的一个随机数:7
找到重复的数为:7
第2次试验
放入1000以内的一个随机数:604
找到重复的数为:604
第3次试验
放入1000以内的一个随机数:667
找到重复的数为:667
第4次试验
放入1000以内的一个随机数:558
找到重复的数为:558
第5次试验
放入1000以内的一个随机数:185
找到重复的数为:185
第6次试验
放入1000以内的一个随机数:933
找到重复的数为:933
第7次试验
放入1000以内的一个随机数:754
找到重复的数为:754
第8次试验
放入1000以内的一个随机数:71
找到重复的数为:71
第9次试验
放入1000以内的一个随机数:390
找到重复的数为:390
第10次试验
放入1000以内的一个随机数:634
找到重复的数为:634

点赞