前置知识点:异或运算的应用
异或^
- A^A=0
- A^0=A
- A^A ^B=B
- 交换律:A^B ^C=A ^C ^B
- 结合律:A^B ^C=A ^(B ^C)
题目:
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次。每个数组元素只能访问一次,设计一个算法,将他找出来;不用辅助存储空间,能否设计一个算法实现?
思路:1.先建立一个1001大小的数组 2.将1-1000的数字填充进数组中
3.在随机产生一个1-1000的随机数 4.利用异或原理
代码:
import java.util.*;
public class 唯一成对的那个数 {
public static void main(String[] args) {
int N=1001;
int []arr =new int[N];
// 前N-1位为从1到N-1
for(int i=0;i<N-1;i++)
{
arr[i]=i+1;
}
// 第N位为随机产生的一个1到N-1的数字
arr[N-1]=new Random().nextInt(N-1)+1;
for(int i=0;i<N;i++)
{
System.out.print(" "+arr[i]);
}
// 利用异或运算
int x=0;
for(int i=1;i<N;i++)
{
x=x^i;
}
for(int i=0;i<arr.length;i++)
{
x=x^arr[i];
}
System.out.println("唯一成对的那个数是:"+x);
}
}
方法二:开辟辅助空间,进行暴力破解
思路:原数组中每出现一个值,就对该值为下标的辅助数组值加一;辅助数组的意思就是记录值为下标的数字出现了几次。
代码:
import java.util.*;
public class 唯一成对的那个数 {
public static void main(String[] args) {
int N=1001;
int []arr =new int[N];
// 前N-1位为从1到N-1
for(int i=0;i<N-1;i++)
{
arr[i]=i+1;
}
// 第N位为随机产生的一个1到N-1的数字
arr[N-1]=new Random().nextInt(N-1)+1;
for(int i=0;i<N;i++)
{
System.out.print(" "+arr[i]);
}
// 方法二:开辟辅助空间,进行暴力破解
int []b=new int[N];
int index=0;
for(int i=0;i<N;i++)
{
b[arr[i]]++;
}
for(int i=0;i<N;i++)
{
if(b[i]==2)
{
System.out.println("唯一成对的数是"+i);
}
}
}
}