题目
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助空间,能否实现。
算法
1.不需要辅助空间
注:因为知道不重复的其他数时哪些所以可以使用此方法,否则只能使用方法二
思路:
只有一个数是出现两次的,联想到 ^ 异或运算中,两个相同的数 异或 得到 0, 0 和任何一个数 异或 还等于这个数(即A^A=0,A^0=A)
设题目中的数组为 arr , 让 arr 与1-1000共1000个数 异或, 这样除了 arr 中重复了两次那个数得到保留外,其它的数均变为0,输出这个数即可
2.需要辅助空间
使用一个1001个元素的数组helper,helper[i] 记录数字 [i] 出现的次数,helper[i]==2 的 i 即为要找的数
代码如下:
package 位运算;
import jdk.jshell.execution.Util;
import java.util.Random;
import java.util.*;
public class wei {
public static void swap(int [] a,int x,int y)
{
int temp;
temp=a[x];
a[x]=a[y];
a[y]=temp;
}
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;
}
//最后一个数是随机数
arr[arr.length-1]=new Random().nextInt(N-1)+1;//nextInt函数作用:该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,随机int值在包含0而不包含n区间内。
//随即下标
int Index=new Random().nextInt(N);
//交换最后一个下标上的数到随机下标位置
swap(arr,Index,arr.length-1);
System.out.println(Arrays.toString(arr));//打印数组的方法
System.out.println("====不建立辅助空间====");
//异或消除重复
int x1=0;
for(int i=1;i<=N-1;i++)
{
x1=(x1^i);//1-1000个数异或
}
for(int i=0;i<N;i++)
{
x1=x1^arr[i];//1-1000个数再与arr中的数异或,得出重复的数
}
System.out.println(x1);
System.out.println("======建立辅助空间的方法=====");
//利用辅助数组的下标代表出现的次数
int[ ] helper=new int[N];
for(int i=0;i<N;i++)
{
helper[arr[i]]++;
}
for(int i=0;i<N;i++)
{
if(helper[i]==2)
{System.out.println(i);
break;}
}
}
}
运行结果:

本文介绍了一种在不使用额外空间的情况下找出数组中重复数字的算法。通过异或运算的独特性质,即相同数字异或结果为0,0与任何数异或结果不变,实现了在仅访问数组元素一次的条件下找到重复的数字。此外,还提供了一种使用辅助数组的方法,通过记录每个数字的出现次数来找出重复数字。
605

被折叠的 条评论
为什么被折叠?



