重复的数:
题目描述:1到1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次,找出这个重复的值。
解法1:巧妙使用位运算
public static void main(String[] args) {
int N = 11;
int[] a = new int[N];
//初始化数组 不包括最后一个元素
for (int i = 0; i < a.length - 1; i++) {
a[i] = i + 1;
}
//数组的最后一个元素是随机数 就是和前面重复的那个数k 模拟这个重复的数字出现在末尾 实际不一定 但是对于算法不影响
a[a.length - 1] = new Random().nextInt(N - 1) + 1;
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(); //打出换行
int x = 0;
for (int i = 1; i < N ; i++) {
x = (x ^ i);
}
for (int i = 0; i < N; i++) {
x = x ^ a[i];
}
System.out.println(x);
}
}
解析:上述算法等价于:1
解法2:使用辅助数组
public static void main(String[] args) {
int N = 11;
int[] a = new int[N];
//初始化数组 不包括最后一个元素
for (int i = 0; i < a.length - 1; i++) {
a[i] = i + 1;
}
//数组的最后一个元素是随机数 就是和前面重复的那个数k 模拟这个重复的数字出现在末尾 实际不一定 但是对于算法不影响
a[a.length - 1] = new Random().nextInt(N - 1) + 1;
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(); //打出换行
// 开辟一个辅助数组空间 每一个数组元素存储的是 原来数组中对应的元素出现的次数 有点像桶排序的计数器
int[] helper=new int[N];
for(int i=0;i<N;i++){
helper[a[i]]++;
}
for(int i=0;i<N;i++){
if(helper[i]==2){
System.out.println(i);
break;
}
}
}
}
总结:
第一种解法的感悟 :此种解法就是要构造K,使其出现次数为奇数次,其余的数据出现次数都是偶素次,
那么连续的疑惑操作之后,偶数次出现的数据都没了,剩下的就是奇数次出现的数据K 但是局限于数据必须连续
第二种解法的感悟:以空间换时间 如果原数据中出现了很大的数据 那么就必须要构造一个很大的辅助数组 但是这种方法适合通用 不必要求数据连续性
落单的数:
题目描述:某一个数组里面只有一个数K出现了一次,其余的都出现了2次,找出这个数。
public static void main(String[] args) {
int[] a=new int[]{1,1,2,2,3,3,4,4,5,5,6,7,7,8,8,9,9,0,0};
int x=0;
for(int i=0;i<a.length;i++){
x=x^a[i];
}
System.out.println(x);
}
//解析:所有出现偶数次的数据 都会在连续的异或之后消掉,只剩下出现奇数次的数据