輸入乙個整數,輸出該數二進位制表示中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的個數。其中負數用補碼表示。解題思路 解法一 這是我當時自己的思路,即通過除二取餘法來求輸入的十進位制數字的二進位制的每一位,再判斷其是否為一,當輸入數字為負數的時候,取其補碼 原數字取反加一 我使用的取...