唯一成对的数(异或的作用)
问题描述如下
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素重复**,**其他均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
三个主要的要求: ① 只存在唯一的一个元素重复 ② 只能访问一次 ③ 不允许使用辅助存储空间
蓝桥杯备战资料《算法之美》 Chapter1——位运算
这是课程展示出来的第一个题目,还真是把我难到了…
要是可以开辅助空间的话,直接暴力扫一遍就可以了。
However, 现在不可以开辅助空间,而且还只能访问一次,双重循环判断的方法也不行。
最后看到了题解,用到位运算中的 异或 ^ ,体现出了异或的另外一个作用,消除重复的元素!
这里的代码只是列举了10个元素的情况,1000个元素只要稍微改一下就可以了, n个元素同理。
如果这个题目没有限定1-1000的范围的话就不能用这个方法来做了,只能通过开通辅助空间来扫了。
// 异或的作用:消除重复!
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int arr[10];
void swap(int &a, int &b) { // 用^来交换整数 效率更高
if(a == b) return;
a = a^b;
b = b^a;
a = a^b;
}
int main() {
srand((int)time(0)); // 改变时间种子,创造随机数
for(int i = 0; i < 9; i++) {
arr[i] = i+1;
}
arr[9] = rand()%9+1; // 1~9之间的随机数
int index = rand()%9; // 0~8之间的随机位置
swap(arr[index], arr[9]); // 交换
for(int i = 0; i < 10; i++) {
cout << arr[i] << " ";
}
cout << endl;
// 以上均为准备工作
// 重点在下面
int x1 = 0;
for(int i = 1; i <= 9; i++) {
x1 ^= i; // x1与所有不重复元素进行一次^
}
for(int i = 0; i < 10; i++) {
x1 ^= arr[i]; // 再对arr中的所有元素进行一次^,那么只留下重复的元素,其他的元素均被消除
}
cout << x1 << endl;
return 0;
}
【END】感谢观看