【leetcode.191】位1的個數
本文轉載自https://leetcode-cn.com/problems/number-of-1-bits/solution/wei-1de-ge-shu-by-leetcode/
一、題目描述
編寫一個函式,輸入是一個無符號整數,返回其二進位制表示式中數字位數為 ‘1’ 的個數(也被稱為漢明重量)。
示例 1:
輸入:00000000000000000000000000001011
輸出:3
解釋:輸入的二進位制串 00000000000000000000000000001011 中,共有三位為 '1'。
示例 2:輸入:00000000000000000000000010000000
輸出:1
解釋:輸入的二進位制串 00000000000000000000000010000000 中,共有一位為 '1'。
示例 3:輸入:11111111111111111111111111111101
輸出:31
解釋:輸入的二進位制串 11111111111111111111111111111101 中,共有 31 位為 '1'。
提示:
請注意,在某些語言(如 Java)中,沒有無符號整數型別。在這種情況下,輸入和輸出都將被指定為有符號整數型別,並且不應影響您的實現,因為無論整數是有符號的還是無符號的,其內部的二進位制表示形式都是相同的。
在 Java 中,編譯器使用二進位制補碼記法來表示有符號整數。因此,在上面的 示例 3 中,輸入表示有符號整數 -3。
二、思路
方法 1:迴圈和位移動
演算法
這個方法比較直接。我們遍歷數字的 32 位。如果某一位是1,則將計數器加一。
我們使用位掩碼來檢查數字的每一位。一開始,掩碼 m=1,因為1的二進位制表示是
0000 0000 0000 0000 0000 0000 0000 0001
顯然,任何數字跟掩碼1進行邏輯與運算,都可以讓我們獲得這個數字的最低位。檢查下一位時,我們將掩碼左移一位。
0000 0000 0000 0000 0000 0000 0000 0010
並重復此過程。
程式碼:
public int hammingWeight(int n) {
int bits = 0;
int mask = 1;
for (int i = 0; i < 32; i++) {
if ((n & mask) != 0) {
bits++;
}
mask <<= 1;
}
return bits;
}
複雜度分析
時間複雜度:O(1)。執行時間依賴於數字n的位數。由於這題中n 是一個 32 位數,所以執行時間是 O(1) 的。
空間複雜度:O(1)。沒有使用額外空間。
方法 2:位操作的小技巧
我們可以把前面的演算法進行優化。我們不再檢查數字的每一個位,而是不斷把數字最後一個1反轉,並把答案加一。當數字變成0的時候偶,我們就知道它沒有1的位了,此時返回答案。
這裡關鍵的想法是對於任意數字n,將n和n-1做與運算,會把最後一個1的位變成0。為什麼?考慮n和n-1的二進位制表示。
在二進位制表示中,數字n中最低位的1總是對應n-1中的0。因此,將n和n-1與運算總是能把n中最低位的1變成0,並保持其他位不變。
使用這個小技巧,程式碼變得非常簡單。
程式碼:
public int hammingWeight(int n) {
int sum = 0;
while (n != 0) {
sum++;
n &= (n - 1);
}
return sum;
}
複雜度分析
時間複雜度:O(1)。執行時間與n中位為1的有關。在最壞情況下,n中所有位都是1。對於 32 位整數,執行時間是 O(1)的。
空間複雜度:O(1)。沒有使用額外空間。
三、後語
位運算確實有意思,對位運算有興趣的同學可以參考我的這篇文章拾遺位運算
相關文章
- 位運算--求一個 數二進位制中1的個數
- 二進位制中1的個數
- 求一個整數的二進位制中1的個數
- 位運算(一):二進位制中1的個數
- leetcode 191 位1的個數LeetCode
- 【c語言】統計一個數二進位制中的1的個數C語言
- poj3252 數位dp(所有比n小的二進位制位0的個數不少於1的個數)記憶化搜尋
- 求一個數的二進位制數中所含1的個數的程式碼實現
- 【劍指offer】二進位制中1的個數
- leedcode 位1的數量
- 【刷演算法】二進位制中1的個數演算法
- 題目1513:二進位制中1的個數
- 求二進位制數中1的個數(程式設計之美)程式設計
- L1-003 個位數統計 pythonPython
- LeetCode每日一題: 位1的個數(No.191)LeetCode每日一題
- 劍指 Offer 15. 二進位制中1的個數
- JZ-011-二進位制中 1 的個數
- 查詢數N二進位制中1的個數(JS版 和 Java版)JSJava
- ACM n-1位數ACM
- 輸入一個整數,返回這個整數的位數
- 【c語言】求兩個數中不同的位的個數C語言
- 【劍指offer中等部分4】二進位制中1的個數(java)Java
- offer通過--10二進位制中統計1的個數-2
- 【MySql】mysql 欄位個數的限制MySql
- 用c語言實現輸入一個十進位制數,計算其轉換為二進位制數後其中包含1的個數C語言
- 輸入一個三位數,輸出它各個數位之和
- 基礎1:有四個數字:1、2、3、4,能組成多少個互不相同且無重複數字的三位數?
- 兩個有序陣列的中位數陣列
- 根據數字二進位制下 1 的數目排序排序
- 二進位制求5個1的格式。。。。
- 找出沒有相鄰的1的二進位制數的個數---2013年2月17日
- 02_Python學習筆記之統計整數二進位制中1的個數Python筆記
- 產生一個32位的16進位制隨機數隨機
- JavaScript 個位數前面加0JavaScript
- L1-003 個位數統計 (15分)(chen-c語言)C語言
- 演算法學習記錄九(C++)--->二進位制中1的個數演算法C++
- 0~9十個數,每個數只能使用一次,組成兩個三位數相加和為四位數的演算法演算法
- 【數位dp入門】51nod 1009 數字1的數量