- 輸入一個(gè)整數(shù),輸出該數(shù)二進(jìn)制表示中1的個(gè)數(shù)。其中負(fù)數(shù)用補(bǔ)碼表示。
思路一:依次右移判斷是否是奇數(shù),也就是判斷最后一位是否是1并計(jì)數(shù)。但是遇到負(fù)數(shù)多次將補(bǔ)位1,可能會造成死循環(huán)。
/**
* 將二進(jìn)制數(shù)右移與1,如果結(jié)果等于1則最右位是1,右移一位繼續(xù)比較
* 存在問題:右移正負(fù)值處理不同可能會出現(xiàn)死循環(huán)
* java中有三種移位運(yùn)算符
*
* << : 左移運(yùn)算符,num << 1,相當(dāng)于num乘以2
*
* >> : 右移運(yùn)算符,num >> 1,相當(dāng)于num除以2
*
* >>> : 無符號右移,忽略符號位,空位都以0補(bǔ)齊
* 本方法左右移,效率高于乘除
* 可以使用無符號右移解決死循環(huán)問題
*/
public int numberOf1_1(int n) {
int count = 0;
while (n !=0){
if ((n & 1) == 1){
count++;
}
n = n >>> 1;
}
return count;
}
思路二:
第一次和1進(jìn)行與操作,后面每次將這個(gè)1乘以2,左移一次,依次比較每一位
/**
* 常規(guī)解法
* 分別與每個(gè)位置上的符號位相與,每次乘以2,意味著左移一位
* @param n
* @return
*/
public int numberOf1_2(int n) {
int count = 0;
int flag = 1;
while (flag != 0){
if ((flag & n) != 0){
count++;
}
flag = flag << 1;
}
return count;
}
思路三:
我們知道如果對數(shù)進(jìn)行減一操作,二進(jìn)制方面所完成的工作是將第一位1改為0,后面有0的話,所有0改為1。所以拿他與原數(shù)與,就可以讓第一個(gè)1和后面所有數(shù)為0,知道所有位為0,找到所有的1。
/**
* 最優(yōu)解法
* 如果一個(gè)二進(jìn)制數(shù)減1,則第一個(gè)為1的二進(jìn)制位變?yōu)?,其后如果有0的話,則全部變?yōu)?
* 將其與數(shù)與操作,如果不為0,則一個(gè)數(shù)為1,繼續(xù)進(jìn)行同樣的操作,一直到數(shù)為0停止
* 那么一個(gè)整數(shù)的二進(jìn)制有多少個(gè)1,就可以進(jìn)行多少次這樣的操作
* @param n
* @return
*/
public int numberOf1(int n) {
int count = 0;
while (n != 0){
count++;
n = (n-1) & n;
}
return count;
}
思路四:直接尋找1,將整數(shù)調(diào)用Integer.toBinaryString(),然后比較
public int numberOf1_3(int n) {
int count = 0;
String binaryN = Integer.toBinaryString(n);
char[] chars = binaryN.toCharArray();
for (int i=0;i<chars.length;i++){
if (chars[i] == '1'){
count++;
}
}
return count;
}
/**
* 判斷一個(gè)整數(shù)是不是2的正整數(shù)次方。
* 直接統(tǒng)計(jì)1的個(gè)數(shù),看其是否等于1
*/
public boolean isExponOf2(int n) {
return numberOf1(n) == 1;
}
/**
* 輸入兩個(gè)整數(shù)m和n,計(jì)算需要改變m的二進(jìn)制表示中的幾位才能得到n。
* 比如10的二進(jìn)制是1010,13的二進(jìn)制是1101,則需要改變3次。
* @param m 一個(gè)整數(shù)
* @param n 另一個(gè)整數(shù)
* @return 需要改變的位數(shù)
*/
public int bitNumNeedsToBeChanged(int m, int n) {
/**
* 關(guān)鍵操作:先做異或操作
* 如果不同則為1,相同為0
* & 與操作,都為1才為1
* | 或操作,都為0時(shí)才為0
*/
return numberOf1(m ^ n);
}
小技巧:
很多題型可以通過統(tǒng)計(jì)二進(jìn)制中1的個(gè)數(shù)來解決。例如求是否是2的整數(shù)次冪,兩個(gè)整數(shù)需要改變二進(jìn)制幾位才能得到另一個(gè)數(shù)就是統(tǒng)計(jì)異或操作后1的個(gè)數(shù)。