传送门:http://acm.bjfu.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1559
题意:给一个数组,里面只有一个数字出现一次,其它数字都出现三次,找出这个出现一次的数字。
分析:数据出少了,用map也可以过- -,后面强行加了数据才把map卡住,本意是想用位运算。如果是其他
数字都出现两次就简单了,所有数字按位异或输出就行。
三次怎么办,我们把数字全部转化成二进制存储,如果我们把 第 ith 个位置上所有数字的和对3取余,3个0或3个1相加余数都为0,那么剩下的值就是单独的那个数。
实现:用32位数组记录数位和,输出模3结果。
int Getnum(int a[],int n) {
int cnt[32]={0}; //初始化
int result=0;//记录和
for(int i=0;i<32;i++) {
for(int j=0;j<n;j++) {
if((a[j]>>i)&1) { //第i位值为1,cnt就+1;
cnt[i]++;
}
}
result |=((cnt[i]%3)<<i);//按位或求和
}
return result;
}
下面是位运算大神用掩码变量优化的做法orz
int singleNumber(int A[], int n) {
int ones = 0, twos = 0, threes = 0;
for (int i = 0; i < n; i++) {
twos |= ones & A[i];
ones ^= A[i];// 异或3次 和 异或 1次的结果是一样的
//对于ones 和 twos 把出现了3次的位置设置为0 (取反之后1的位置为0)
threes = ones & twos;
ones &= ~threes;
twos &= ~threes;
}
return ones;
}
http://oj.leetcode.com/discuss/857/constant-space-solution
ones,twos,threes分别代表第
ith
位只出现一次,两次,三次的掩码变量
else:给一个数组,里面有两个数字出现一次,其它数字都出现两次,找出这两个出现一次的数字。