找出数组中唯一成对的那个数

题目介绍

1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助空间,能否实现?

解题思路

1. 不使用辅助空间

不使用辅助空间,我们可以想到的是用异或 ( ^ ) 来解决问题。

异或的用法是:A0=A,AA=0。我们可以得到,当相同的数进行异或的时候,就会得到0。这个时候得到的数组的那个成对的数就会异或为0。但是如果,我们将这个数组与 1-1000的数进行异或,剩下的数就是唯一成对的那个数 。
( A^ B^ B^ C… ) ^ ( A^ B^ C… )A^ A^ B^ B^ B^ C^ C… 这个结果得到的就是 B ,即就是我们要的结果,数组中唯一成对的那个数。

核心代码
int N = 1001;
int result = 0;
for (int i = 1; i <= N-1; i++) {
	result = result^i;//result 从 1异或到1000
}
for (int i = 0; i < N; i++) {
	result = result^arr[i];//result与数组中的所有元素进行异或
}
完整代码

为了使代码 main 函数代码看上去更简洁,我将 交换数组元素的值 和 输出数组 写成两个方法

public static void main(String[] args) {
		int N = 1001;
		int[] arr = new int[N];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = i + 1;
		}
		//最后一个数,是随机数
		arr[arr.length-1] = new Random().nextInt(N-1);
    	//取随机索引,将上一行代码生成的随机数,插入到arr数组中去
		int index = new Random().nextInt(N);
		swap(arr, index, arr.length-1);			//交换数组元素的值
		print(arr);								//输出数组元素
		
		int result = 0;
		for (int i = 1; i <= N-1; i++) {
			result = result^i;
		}
		for (int i = 0; i < N; i++) {
			result = result^arr[i];
		}
		System.out.println("数组中唯一成对的那个数是"+result);
		  
	}
	//交换数组元素的值
	public static void swap(int[] arr, int i, int j) {
	    int tmp = arr[i];
	    arr[i] = arr[j];
	    arr[j] = tmp;
	}
	//输出数组
	public static void print(int[] arr) {
		 for (int i : arr) {
			System.out.print(i+" ");	
		 }
		 System.out.println("");
	}

2. 开辟辅助空间

这种方法,也就是创建一个数组,我姑且把这个新数组命名为 helper,开辟辅助空间的原理就是记录 arr 数组出现过的数,即,arr 数组的元素值,为 helper 数组的索引,当出现一个 读取 arr 数组元素值的时候,就在 helper 数组的索引加 1 ,因为存在成对的数,所以当遍历完整个 arr 数组之后, helper 数组中索引是成对的那个数的元素值为2,输出 helper 数组中,元素为2的那个数组,就是我们要找的数组中出现成对的那个数。

也许上面的话,可能有点饶,看下面的核心代码也许你就理解了。

核心代码
int[] helper = new int[N];
		for (int i = 1; i < N; i++) {
			helper[arr[i]]++;
			//arr[i]是一个1-1000数的范围
			//helper数组给 arr数组出现的数进行计数,理解为arr每出现一个数,helper数组就以这个数为索引的值进行自增。
		}
		for (int i = 1; i < N; i++) {
			if (helper[i]==2) {
				System.out.println("重复的那个数是"+i);
			}
		}

感谢大家的阅读,如果对上述内容有什么疑问的话,欢迎各位留言。(学习算法的第一天打卡,脑阔疼。)

结了,如果是找出数组中落单的那个数,那就更简单了,直接对这个数组进行异或即可。

小陈爱写代码

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值