本文参考自《剑指offer》一书,代码采用Java语言。html
更多:《剑指Offer》Java实现合集 java
在一个数组中除了一个数字只出现一次以外,其余数字都出现了三次。请找出那个只出现一次的数字。数组
这道题中数字出现了三次,没法像56-1) 数组中只出现一次的两个数字同样经过利用异或位运算进行消除相同个数字。可是仍然能够沿用位运算的思路。post
将全部数字的二进制表示的对应位都加起来,若是某一位能被三整除,那么只出现一次的数字在该位为0;反之,为1。测试
测试算例 url
1.功能测试(惟一出现的数字是0,正数,负数;重复出现的数字是0,正数,负数)htm
//题目:在一个数组中除了一个数字只出现一次以外,其余数字都出现了三次。请 //找出那个只出现一次的数字。 public class NumberAppearingOnce { public static int findNumberAppearingOnce(int[] arr) { if(arr==null || arr.length<=0) throw new RuntimeException(); int[] bitSum = new int[32]; for(int i=0;i<32;i++) bitSum[i]=0; for(int i=0;i<arr.length;i++) { int bitMask=1; for(int j=31;j>=0;j--) { int bit=arr[i]&bitMask; //注意arr[i]&bitMask不必定等于1或者0,有可能等于00010000 if(bit!=0) bitSum[j]+=1; bitMask=bitMask<<1; } } int result=0; for(int i=0;i<32;i++) { result=result<<1; result+=(bitSum[i]%3); //result=result<<1; //不能放在后面,不然最前面一位就没了 } return result; } }
1.判断某个数x的第n位(如第3位)上是否为1,blog
1)经过 x&00000100 的结果是否为0 来判断。(不能根据是否等于1来判断)get
2)经过(x>>3)&1 是否为0 来判断it
2.经过number&bitMask的结果是否为0(不能用1判断),bitMask=1不断左移,能够将一个数的二进制存储到32位的数组中。
int number=100; int bitMask=1; for(int j=31;j>=0;j--) { int bit=number&bitMask; //注意arr[i]&bitMask不必定等于1或者0,有可能等于00010000 if(bit!=0) bits[j]=1; bitMask=bitMask<<1; }
3.经过如下代码实现二进制转化为数字(注意左移语句的位置):
int result=0; for(int i=0;i<32;i++) { result=result<<1; result+=bits[i]; //result=result<<1; //不能放在后面,不然最前面一位就没了 }