題目描述:
輸入一個整數,輸出該數二進制表示中1的個數,其中負數用補碼錶示。
注意:整數在計算機中本身就是以二進制形式存儲的。
主要使用的是位運算。
補碼的移位:
左移:正負數均是在右邊補0;
右移:正數是在左邊補0,負數是在左邊補1。
方案1:
依次將1左移,與該數做&運算。
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
int tmp = 1;
while(tmp){
if(n & tmp){
count++ ;
}
tmp = tmp << 1;
}
return count;
}
};
運行時間:4ms
佔用內存:480K
方案2:該數與1做&運算,但要注意循環條件,因爲當爲負數時,負數右移左邊補1,所以可能陷入無限循環,因此需要控制其位數。該方案需要一共執行判斷32次。
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
int tmp = 0;
while(tmp < 32){
if(n & 1){
count++ ;
}
n = n >> 1;
tmp++;
}
return count;
}
};
運行時間:3ms
佔用內存:384K
方案3:x&(x-1)可以將整數的最右邊的1變爲0,根據這個,我們只需循環判斷x = x&(x-1) 是否爲0,即可統計1的個數。該方案相比方案2而言減少了循環的次數。
eg:-5二進制中1的個數。
x |
x&(x-1) |
0101 |
0101 & 0100 = 0100 |
0100 |
0100 & 0011 = 0000 |
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while(n){
count++;
n = n & (n-1);
}
return count;
}
};
運行時間:3ms
佔用內存:480K
方案4:使用輾轉相除法。
注意:該方案只能用於正數,不能用於負數。
eg: -1 % 2 != 1,count =0;但實際上-1的二進制中有32個1。
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while(n){
if(n % 2 == 1){
count++;
}
n = n/2;
}
return count;
}
};
參考鏈接:
http://www.cnblogs.com/AndyJee/p/4630568.html
https://blog.csdn.net/zhao_miao/article/details/79747664