劍指Offer 11 二進位制中1的個數

2021-09-24 16:00:32 字數 1644 閱讀 6372

輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。

思路:

先來看一下wangdongli_1993部落格中總結的原碼、反碼、補碼的知識:

數字在計算機中都是二進位制來存在,以位元組為單位,乙個位元組是8位,這個題目是int型別就是32位

原碼:最高位是符號位,剩下的表示機器數的值

+1:0000 0001

-1:1000 0001

反碼:對於整數,反碼同原碼,對於負數符號位不變,剩下的位取反

+1:0000 0001

-1:1111 1110

補碼:對於整數,補碼同源,對於負數反碼的基礎加1

+1:0000 0001

-1:1111 1111

之後看到了cytues部落格的分析覺得說的很明白,我在這裡再囉嗦一番:

當n不為0的時候,n的二進位制至少有一位是1。

第一種方法比較簡單暴力,因為輸入是整數,int型整數是32位,因此利用for迴圈,用n和1進行按位與操作(低位依次相與),然後將n右移,進行32次這樣的操作之後就能得到n中1的個數。

第二種方法相比第一種更有技巧一些,我們先來看正數的情況,由預備知識可知,正數的最高位為0,且原碼、反碼、補碼相同,有乙個技巧是先將n減一操作,這個時候n的二進位制表示從右向左數的第乙個1將變成0,而其右側的所有0將變成1,其左側所有數不變。舉個例子,比如整數12,二進位制為1100,在減一之後變成1011,可以看到,12在減1之後,其右側第乙個1變成0,且1右邊所有0變成1,1左側所有數不變。我們將1100與1011進行與操作,可以發現變成1000,這個時候12的二進位制表示最右側1消失了,這個方法的關鍵就在於此,對整數進行多次減1相與的操作,會將整數二進位制中1逐步消除,最終變為0,所以我們的結論是,乙個正數,能進行多少次這樣的與操作,其二進位制表示就會有多少個1。

我們再來看一下負數的情況,負數以補碼的形式儲存在計算機中,其最高位為符號位,始終為1,所以對負數進行上述操作的時候會出現乙個問題,往右移,符號位不變,符號位1往右移,最終可能會出現全1的情況,導致死迴圈。與0xffffffff相與,就可以消除負數的影響。

solution:

python

(1)# -*- coding:utf-8 -*-

class solution:

def numberof1(self, n):

# write code here

count = 0

for i in range(32):

if n&1 ==1:

count += 1

n = n>>1

return count

(2)# -*- coding:utf-8 -*-

class solution:

def numberof1(self, n):

# write code here

if n < 0:

n = n&0xffffffff

count = 0

while n:

n = n&(n-1)

count += 1

return count

reference:

wangdongli_1993: 

cytues:

劍指Offer 11 二進位制中1的個數

思路 如果乙個整數不為0,那麼這個整數至少有一位是1。如果我們把這個整數減1,那麼原來處在整數最右邊的1就會變為0,原來在1後面的所有的0都會變成1 如果最右邊的1後面還有0的話 其餘所有位將不會受到影響。舉個例子 乙個二進位制數1100,從右邊數起第三位是處於最右邊的乙個1。減去1後,第三位變成0...

劍指offer 11 二進位制中1的個數

輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。用1 1自身左移運算,其實後來就不是1了 和n的每位進行位與,來判斷1的個數 public class solution11 flag flag 1 return count public static void main strin...

《劍指Offer》11 二進位制中1的個數

題目 11.二進位制中1的個數 知識點 位運算 題目描述 輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。解題思路 解法一 這是我當時自己的思路,即通過除二取餘法來求輸入的十進位制數字的二進位制的每一位,再判斷其是否為一,當輸入數字為負數的時候,取其補碼 原數字取反加一 我使用的取...