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; } };