前言
最近會手寫一些常考的面試題目,測試通過后會跟大家分享一下
移位法
僅適應于正數的做法:
移位法就是每次判斷n的二進制的最低位是否為1,時間復雜度為O(logn)
復制代碼代碼如下:
int nativeOnenum(int n)
{
int count = 0;
while (n) {
if (n & 1) count ++;
n >>= 1;
}
return count;
}
對于正數沒問題,但是如果n為負數,這里就出現問題了,以負數-8為例,二進制補碼形式為11111111|11111111|11111111|11111000|,右移一位之后,變成了11111111|11111111|11111111|11111100|,因為是負數,所以符號位會一直補1,導致最后全1,出現死循環
針對這種情況,我們可以用變量flag =1,從右向左去和n比較,32位int最多比較32次即可知道n中1的數量
復制代碼代碼如下:
int oneNum(int n)
{
int count, flag;
for (count = 0, flag = 1; flag; flag <<= 1) {
if (flag & n) count ++;
}
return count;
}
快速法
這種解法的思路是,二進制中1的個數只與1的位數有關,n & (n - 1)快速的去掉最左邊的1,例如7(0111) & 6(0110)= 6(0110),快速的去掉了最左邊的1
復制代碼代碼如下:
int quickOne(int n)
{
int count = 0;
while (n) {
count ++;
n = n & (n - 1);
}
return count;
}