劍指offer 二進制中1的個數

題目描述
輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。

\color{blue}解題思路:
這道題有一個公式 n &= (n - 1),也就是計算n的二進制表示1的個數,只要循環使用上面的公式,直到n爲0。這個公式不知道就記住即可,下面用個示例簡單驗證一下公式的正確性,不是很嚴謹。

假設 n = +127,則二進制形式爲"0111 1111"(假設長度爲一個字節,最高位爲符號位,0表示正數,1表示負數)
第一次計算,n = +127,n & (n - 1) == "0111 1111" & "0111 1110" == "0111 1110"(十進制爲+126)
第二次計算,n = +126,n & (n - 1) == "0111 1110" & "0111 1101" == "0111 1100"(十進制爲+124)
第三次計算,n = +124,n & (n - 1) == "0111 1100" & "0111 1011" == "0111 1000"(十進制爲+120)
第四次計算,n = +120,n & (n - 1) == "0111 1000" & "0111 0111" == "0111 0000"(十進制爲+112)
第五次計算,n = +112,n & (n - 1) == "0111 0000" & "0110 1111" == "0110 0000"(十進制爲+96)
第六次計算,n = +96, n & (n - 1) == "0110 0000" & "0101 1111" == "0100 0000"(十進制爲+64)
第七次計算,n = +96, n & (n - 1) == "0100 0000" & "0011 1111" == "0000 0000"(十進制爲+0)
第八次計算,n = 0,停止計算            

不難發現,每次計算n & (n - 1),都是把n的二進制形式最後一位1置爲0.
當n爲負數的時候,需要用補碼形式計算,而計算機中默認就是補碼(正數的補碼與原碼相同,
負數的補碼是原碼除符號位外各位取反再+1)形式存儲,所以計算過程類似。
(如果原碼、補碼不知道是什麼的話,那就跳過吧。 

\color{blue}代碼實現:

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         while (n != 0) {
         	 //統計n的二進制形式1的個數
             n &= (n - 1);
             count += 1;
         }
         return count;
     }
};

在這裏插入圖片描述
\color{blue}題目推薦:
題1、LeetCode 搜索插入的位置(二分查找)
題2、LeetCode 搜索旋轉排序數組(二分搜索)
題3、LeetCode 在排序數組中查找元素的第一個和最後一個位置(二分查找)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章