題目描述
輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。分析
計算機中正數就是原碼表示,負數用補碼表示,所以不需要我們自己把數字轉化為二進位制。題目中說到負數用補碼表示,實際上計算機中的負數就是用補碼表示的。所以,輸入的數字我們也可以直接當成二進位制就行。
1、可能引起死迴圈的解法:
每次都用最右邊一位判斷是不是1,判斷完後,然後右移一位。
如果是正數,右移一位後,最高位設為0;
如果是負數,右移一位後,最高位設為1,因為要保證移位後還是個負數。
如:0x80000000 右移一位後 變成 0xc0000000 而不是 0x40000000
如果一直做右移運算,最終這個數字會變成0xffffffff,陷入死迴圈。
在數學上,把正數右移一位看起來跟除以2是等價的,但是可以把右移運算換成除以2嗎?
答案是不可以,因為除法效率比移位運算要低得多。
let count=0;
while
(n)return count;
2、常規解法:
右移可能陷入死迴圈。
可以進行左移。
flag=1;一直左移最後會變成0。
count計算有多少個1
先用1與輸入的數字進行與運算,判斷是不是1,如果為真count++;再把1左移一位(10),與數字進行與運算,判斷是不是1,如果為真count++;再把2左移一位(100),與數字進行與運算,判斷是不是1,如果為真count++…。
let count=0;
let flag=1;
while
(flag)
return count;
32為的整數需要迴圈32次
3、優解:
有多少個1,就迴圈多少次。
將乙個數減1,如果不為0,說明這個數有1。
將輸入的數減1,最右邊(第m位)的1變為0,第m位右邊的數由0變為1,第m位左邊的數不變,然後與原來的數進行與運算。
如:1100減去1,變成1011,1011&1100得出1000;1000減去1,變成0111,0111&1000得出0。進行了兩次操作,得出有兩個1。
把乙個整數減去1,再和原整數做與運算,會把整數最右邊乙個1變成0(每次都將最右邊的1乾掉)。那麼乙個整數的二進位制有多少個1,就可以進行多少次這樣的操作。
}關鍵點 :位運算
知識點:進製轉化 補碼反碼原碼
參考《劍指offer》
11 劍指offer第十一題(python)
問題 輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。coding utf 8 class solution def numberof1 self,n write code here count 0 if n 0 n n 0xffffffff while n count 1 n n...
《劍指offer》第十一 十二題(js)
輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。在討論區學習來的方法,太妙了 方法一n 1 會將 n 最右邊的 1 及其右邊的 0 全部取反,再用 n 與它進行按位與運算,那麼就將原本最右邊的 1 及其右邊的 0 全部置為了 0,其餘位置不受影響。n 有多少個1 就會進行多少次這樣...
劍指offer第十一題 旋轉陣列的最小數字
把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。coding utf 8 classsolution defminnum...