题目描述:
在含有N个元素的数组中放1-N之间的数,只有唯一一个元素重复,其他均只出现一次,每个数组元素只能访问一次,设计算法,将其找出!
解法一:使用位运算
数组的元素做异或运算,得到的结果和1-N个数做异或运算,1-N之间的数互相消除,只剩下成对的数.
代码如下(JAVA代码)
int N = 1001;
int arr[] = new int[N];
Random getnum = new Random();
int index = getnum.nextInt(N);//获取的随机插入的索引
int num = getnum.nextInt(N);//构造成对的数
for(int i = 0;i<arr.length-1;i++){
arr[i] = i;
}
//将生成的数放入到随机索引的位置
arr[N-1] = num;
int temp = arr[index];
arr[index] = arr[N-1];
arr[N-1] = temp;
//异或运算
int result1 = arr[0];
for(int i = 0;i<arr.length;i++){//数组内异或运算
result1^=arr[i];
}
for(int j = 0;j<N-1;j++){//0到N-1个数异或运算
result1^=j;
}
System.out.println(num+" "+result1);
解法二:借助辅助空间;
开辟一个比arr数组小一的数组helper,因为arr数组中的元素是连续的,所以遍历arr数组的同时,将arr数组中的元素对应helper的下标的值做++运算,这样helper数组中存的就是下标与arr数组元素相同的数出现的次数.
因为只有一个成对的数,找出helper数组元素等于2的下标即可得到结果;
代码如下:
int[] helper = new int[N-1];
for(int i = 0;i<N;i++){
helper[arr[i]]++;
}
for(int i = 0;i<helper.length;i++){
if(helper[i]==2){
System.out.println(i);
break;
}
}