数组中只出现一次的数目字
数组中只出现一次的数字
- 题目描述:
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
- 输入:
-
每个测试案例包括两行:第一行包含一个整数n,表示数组大小。2<=n <= 10^6。第二行包含n个整数,表示数组元素,元素均为int。
- 输出:
- 对应每个测试案例,输出数组中只出现一次的两个数。输出的数字从小到大的顺序。
- 样例输入:
-
8 2 4 3 6 3 2 5 5
- 样例输出:
-
4 6
http://ac.jobdu.com/problem.php?cid=1039&pid=22
扩展:寻找数组中只出现一次的三个数。
解题思想:
先看一个简单的实例,若是找数组中只出现一次的一个数,其它的数都出现两次,直接对数组元素进行位异或就可以得到数组中只出现一次的一个数。本题中,找数组中只出现一次的两个数,则要将数组分成2个子数组,每个子数组中仅存在出现一次的一个数。关键就在于分组的标准,而对数组中所有的元素进行异或,得到的是这个数的异或。这个结果不为0,则一定存在某一个数字的一位为1,另一个数字中的某位为0,这样异或的结果才不为0。因此分组的标准是对数组元素全部进行异或的结果中首位为1的那一位(假设是第N位)。然后以这个数与数组中元素进行与运算,进行分组。数组元素第N位为1的分一组,为0为另一组。在每个子数组中进行全部异或,最终可以得出数组中只出现一次的两个数。
代码如下:
#include <iostream> #include <cstdio> #define MAX 1000001 using namespace std; int shuzu[MAX]; int main() { int n,i; while (scanf("%d",&n)!=EOF) { int result = 0; for (i=0;i<n;i++) { scanf("%d",shuzu+i); result^=shuzu[i]; } int t; for (t=1;t<=result;t<<=1) { if (t&result) break; } int a=0,b=0; for (i=0;i<n;i++) { if (t&shuzu[i]) a^=shuzu[i]; else b^=shuzu[i]; } a<b?printf("%d %d\n",a,b):printf("%d %d\n",b,a); } return 0; } /************************************************************** Problem: 1351 User: hnuzengchao Language: C++ Result: Accepted Time:920 ms Memory:5416 kb ****************************************************************/