位运算:找出唯一成对的数

一、题目

将1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来。

二、补充知识

random(100)//生成[0,100)的随机数
random.nextInt(30)//生成[0.30)的随机数

异或(^):相同则为0,不同则为1;
1、0 ^ A = A;(A为任何数)
2、异或可以消除重复,A ^ A = 0;

1、不采用辅助空间解法

>>解题思路

目前题目要求:每一个数组元素只能访问一次;不采用辅助空间
思路为“异或可以消除重复”,即A ^ A = 0,那么A ^ A ^ A = A,就可以找出重复的数A.
如:将1-4这4个数放在含有5个元素数组
arr[5] = { 1, 2, 3, 4, 2};
1 ^ 2 ^ 3 ^ 4 ^ 2 ^ 1 ^ 2 ^ 3 ^ 4 = 2
在这里插入图片描述

>>主要代码(完整代码在文章末尾)

		//不采用辅助空间,位运算找到重复的数
		int x = 0;
		for(int i = 1; i <= N-1; i ++){
			x = (x ^ i);    //构造1 - (N-1)的^
		}
		for(int i = 0; i < N; i ++){
			x = x ^ arr[i]; //使数组中每一个数与构造的 (1 - (N-1))进行^
		} 
		System.out.print("\n不采用辅助空间重复数字为:" + x);


2、采用辅助空间解法

>>解题思路

1、新开一个辅助数组arr2
2、由于数组arr中的数只有一个是重复的,并且是从1 - (N-1)连续的,那么可以将这些连续的数作为arr2的下标,让该下标数组元素值 ++(初始值都为0)
如此,必有一个数组元素值为2,因为重复++了2次
3、再循环遍历arr2,判断哪个元素为2,输出该下标,即为重复的数。


>>主要代码(完整代码在文章末尾)

//采用辅助空间
		int[] arr2 = new int[N];
		for(int i = 0; i < N; i ++){
			arr2[arr[i]] ++;
		}
		for(int i = 0; i < N; i ++){
			if(arr2[i] == 2){
				System.out.print("\n采用辅助空间重复数字为:" + i);
				break;
			}
		}


三、完整代码

package lanqiao;

import java.util.Arrays;
import java.util.Random;

public class test01 {
	public static void main(String[] args){
		int N = 1001;
		int[] arr = new int[N]; 
		for(int i = 0; i < arr.length-1; i ++){
			arr[i] = i+1;  //填充数组数据
		} 
		//最后一个数据从1 - (N-1)中随机填充(也就是指定重复的那一个数)
		arr[arr.length-1] = new Random().nextInt(N-1) + 1;
		//找到随机的数组下标
		int index = new Random().nextInt(N-1);
		
		//将重复值打乱到数组中
		int temp = arr[index];
		arr[index] = arr[arr.length-1];
		arr[arr.length-1] = temp;
		System.out.print(Arrays.toString(arr));
		
		//不采用辅助空间,位运算找到重复的数
		int x = 0;
		for(int i = 1; i <= N-1; i ++){
			x = (x ^ i);    //构造1 - (N-1)的^
		}
		for(int i = 0; i < N; i ++){
			x = x ^ arr[i]; //使数组中每一个数与构造的 (1 - (N-1))进行^
		} 
		System.out.print("\n不采用辅助空间重复数字为:" + x);
		
		System.out.print("\n———————————————————————————————————");
		
		//采用辅助空间
		int[] arr2 = new int[N];
		for(int i = 0; i < N; i ++){
			arr2[arr[i]] ++;
		}
		for(int i = 0; i < N; i ++){
			if(arr2[i] == 2){
				System.out.print("\n采用辅助空间重复数字为:" + i);
				break;
			}
		}
		
	}
}

发布了15 篇原创文章 · 获赞 6 · 访问量 1065

猜你喜欢

转载自blog.csdn.net/qq_40306266/article/details/103963063