【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)。沒有使用額外空間。
三、後語
位運算確實有意思,對位運算有興趣的同學可以參考我的這篇文章拾遺位運算
相關文章
- leetcode 191 位1的個數LeetCode
- 1的個數 【位運算】
- 二進位制中1的個數
- LeetCode每日一題: 位1的個數(No.191)LeetCode每日一題
- leedcode 位1的數量
- 【劍指offer】二進位制中1的個數
- JZ-011-二進位制中 1 的個數
- L1-003 個位數統計 pythonPython
- 【刷演算法】二進位制中1的個數演算法
- 劍指 Offer 15. 二進位制中1的個數
- 輸入一個整數,返回這個整數的位數
- offer通過--10二進位制中統計1的個數-2
- 【劍指offer中等部分4】二進位制中1的個數(java)Java
- 一個大整數至少有多少個1 (每一位都是1)能整除2013
- 輸入一個三位數,輸出它各個數位之和
- 02_Python學習筆記之統計整數二進位制中1的個數Python筆記
- 兩個有序陣列的中位數陣列
- 二進位制求5個1的格式。。。。
- 根據數字二進位制下 1 的數目排序排序
- L1-003 個位數統計 (15分)(chen-c語言)C語言
- JZ-068-列印從 1 到最大的 n 位數
- 輸出由1、2、3、4四個數字組成的每位都不相同的所有三位數
- 數位電路(1)- 邏輯代數第一講
- 【遞迴打卡1】在兩個長度相等的排序陣列中找到上中位數遞迴排序陣列
- 分治與遞迴-找k個臨近中位數的數遞迴
- 力扣 根據數字二進位制下1的數目排序力扣排序
- LeetCode-兩個排序陣列的中位數LeetCode排序陣列
- 尋找兩個有序陣列的中位數陣列
- 4. 兩個排序陣列的中位數排序陣列
- 1021. 個位數統計 (15)
- 數數的位數(正整數)
- CCF 201512-1 數位之和 python 滿分Python
- 三種語言實現計算二進位制中1的個數(C++/Python/Java)C++PythonJava
- 位運算-判斷一個數是否為2的整數次方
- leetcode-1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- leetcode.1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- leetcode1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- VBAP和VBEP的幾個數量欄位的說明