Given an array of integers, every element appears
three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
自己的做法是先对数组进行一次排序,然后从前往后扫描统计个数。这样做虽然能AC,但是改变原有的数组,并不是好的方法
class Solution {
public:
int singleNumber(int A[], int n) {
if(n==0) exit(0);
sort(A,A+n);
int x = A[0];
int times = 1;
for(int i=1;i<n;++i){
if(x==A[i]) {
++times;
continue;
}else{
if(times == 1) break;
x = A[i];
times = 1;
}
}
return x;
}
};
以下是网上大家的方法。
1.用个数组记录各个位出现的次数
class Solution {
public:
int singleNumber(int A[], int n) {
if(!n) exit(0);
int bits[32];
memset(bits,0,sizeof(bits));
int result=0;
for(int i=0;i<n;++i){
for(int j=0;j<sizeof(bits)/sizeof(int);++j){
if((A[i]>>j)&1) ++bits[j];
}
}
for(int j=0;j<sizeof(bits)/sizeof(int);++j){
result |= ((bits[j]%3)<<j);
}
return result;
}
};
2.思想:用三个掩码ones,twos,threes表示第i位出现了一次,两次,三次。但第i位出现3次时,把ones和twos重新置位。这里注意下ones,其做异或运算,当第i位出现1次时,第i位为1,两次时为0,三次时又为1。
class Solution {
public:
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];
threes =ones & twos;
ones &= ~threes;
twos &= ~threes;
}
return ones;
}
};