15. 二進位中 1 的個數(劍指 Offer 題解Java版)

2020-12-24 酷扯兒

本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】經微信公眾號授權轉載,如需轉載與原文作者聯繫

文章目錄

15. 二進位中 1 的個數題目連結題目描述思路一. 利用Integer類的bitCount()二. 常規循環三. n&(n-1)

15. 二進位中 1 的個數

題目連結

NowCoder

題目描述

任意給定一個32位無符號整數n,求n的二進位表示中1的個數,比如n = 5(0101)時,返回2,n = 15(1111)時,返回4

這也是一道比較經典的題目了,相信不少人面試的時候可能遇到過這道題吧,下面介紹了幾種方法來實現這道題,相信很多人可能見過下面的算法,但我相信很少有人見到本文中所有的算法。如果您上頭上有更好的算法,或者本文沒有提到的算法,請不要吝惜您的代碼,分享的時候,也是學習和交流的時候。

思路

一. 利用Integer類的bitCount()

代碼實現

package 二進位一的個數;/*

作者 :XiangLin

文件 :BitCount1.java

IDE :IntelliJ IDEA

*/

public class BitCount1 {

public static int numberOfOne(int n){

return Integer.bitCount(n);

}

public static void main(String[] args) {

System.out.println("數字 10的二進位表示中的1的個數:"+numberOfOne(10));

}

}

二. 常規循環

時間複雜度O(logN)

因為是統計1的個數,那麼用輸入整數的每一位與1的位與運算就可以簡單的實現

代碼實現

public class BitCount2 {

public static int numberOfOne(int n){

int result = 0;// 記錄數字中1的位數

for (int i = 0; i <= 32; i++){//int佔32bit

result += (n&1);

n >>>= 1;

}

return result;

}

public static void main(String[] args) {

System.out.println("數字 9的二進位表示中的1的個數:"+numberOfOne(9));//2

}

}

是最簡單的方法,有點程序基礎的人都能想得到,那就是移位+計數,很簡單,不多說了,直接上代碼,這種方法的運算次數與輸入n最高位1的位置有關,最多循環32次。

public class BitCount2{

public static int numberOfOne(int n){

int result = 0;

while (n > 0){

if ((n & 1) == 1){

++ result;

}

n >>>= 1;

}

return result;

}

public static void main(String[] args) {

System.out.println("數字 11的二進位表示中的1的個數:"+numberOfOne(11));//2

}

}

三. n&(n-1)

時間複雜度,其中 M 表示 1 的個數。

一個結論

結論:一個數與該數減一的結果進行與運算n&(n-1),會把該數右邊(低位)第一個1變為0,而該位左邊保持不變(高位)

例子:比如1100(對應十進位是12),減去1之後的結果是1011(也就是十進位的11),兩個數進行與運算之後,我們發現最後的結果是1000(對應十進位的8,當然這個8與後面沒有關係,可以略過)。這樣我們每進行一次的與運算就消去一個1,這樣消到最後肯定是0了,所以我們可以在代碼中以這個為循環的終止條件。

package 二進位一的個數;

/*

作者 :XiangLin

文件 :BitCount3.java

IDE :IntelliJ IDEA

*/

public class BitCount3 {

public static int numberOfOne(int n){

int result = 0;// 記錄數字中1的位數

while (n != 0){// 數字的二進位表示中有多少個1就進行多少次操作

result ++;

n = n&(n-1);

}

return result;

}

public static void main(String[] args) {

System.out.println("數字 9的二進位表示中的1的個數:"+numberOfOne(9));

}

}

相關焦點

  • 【二進位】----十進位數轉換成二進位數
    你一定會說不就是0、1、2、3、4、5、6、7、8、9這些數嗎?你說對了。這些我們生活中常見的數字,一共有10個,最大的是9,如果再加1,就要進位了,變成兩位數10了。這樣由0--9十個數字來表示並且進位規則是「逢十進一」,借位規則是「借一當十」就是我們常說的十進位的數。你知道嗎?
  • 劍指 Offer 55 - II. 平衡二叉樹 - leetcode 劍指offer系列
    題目難度: 簡單原題連結[1]今天繼續更新劍指 offer 系列, 老樣子晚上 6 點 45 分準時更新公眾號 每日精選算法題, 大家記得關注哦~ 另外在公眾號裡回復 offer 就能看到劍指 offer 系列當前連載的所有文章了題目描述輸入一棵二叉樹的根節點,判斷該樹是不是平衡二叉樹。
  • 二進位、八進位、十進位、十六進位數的轉換方法
    在計算機中:D7 D6 D5 D4 D3 D2 D1 D0 只有兩種0和18 4 2 1二)、數制轉換不同進位計數制之間的轉換原則:不同進位計數制之間的轉換是根據兩個有理數如相等,則兩數的整數和分數部分一定分別相等的原則進行的。也就是說,若轉換前兩數相等,轉換後仍必須相等。
  • 二進位、八進位、十進位和十六進位數之間的轉換方法
    數制的基本概念數碼數制中表示基本數值大小的不同數字符號。例如,十進位有10個數碼:0、1、2、3、4、5、6、7、8、9。基數數制所使用數碼的個數。例如,二進位的基數為2;十進位的基數為10。位權數制中某一位上的1所表示數值的大小(所處位置的價值)。
  • 18.1在 O(1) 時間內刪除鍊表節點(劍指 Offer 題解Java版)
    O(1)時間刪除該結點。解題思路①如果該節點不是尾節點,那麼可以直接將下一個節點的值賦給該節點,然後令該節點指向下下個節點,再刪除下一個節點,時間複雜度為O(1)。②否則,就需要先遍歷鍊表,找到節點的前一個節點,然後讓前一個節點指向null,時間複雜度為O(N)。
  • 【S7-200】二進位、八進位、十進位、十六進位數的轉換方法
    一般計數都採用進位計數,其特點是:(1)逢N進一,N是每種進位計數制表示一位數所需要的符號數目為基數。(2)採用位置表示法,處在不同位置的數字所代表的值不同,而在固定位置上單位數字表示的值是確定的,這個固定位上的值稱為權。
  • 十進位數的二進位編碼
    在人機互動過程中,為了既滿足系統中使用二進位數的要求,又適應人們使用十進位數的習慣,通常用4位二進位代碼對十進位數字符號進行編碼,簡稱為二-十進位代碼,或稱BCD(Binary Coded Decimal)碼。
  • 十進位數與二進位數的相互轉化
    最近,高二年級中有n多個同學問我:「老師,怎樣將十進位數轉化為二進位數呢?如果轉化為八進位數呢?」
  • Python零基礎入門——認識二進位數
    這節課我們主要學習二進位數。為什麼要學習二進位數呢?因為二進位數只有兩個數字0和1,因此二進位數非常適合描述電路的通與短、開關的打開與關閉。例如,我們可以用二進位數0和1來表示燈泡的亮與不亮,用二進位數0來表示燈泡不亮,用二進位數1來表示燈泡亮,這樣我們就可以用多個二進位數來表示燈泡的亮與不亮了。如01011表示有三個燈泡亮,兩個燈泡不亮。
  • 藍橋專題之二進位數數(及其優化)
    二進位數數問題描述給定L,R。統計[L,R]區間內的所有數在二進位下包含的「1」的個數之和。如5的二進位為101,包含2個「1」。通過變量計數二進位數中1的個數    }    printf("%d", count);    return 0;}將整數表示為二進位的方法在上面已經講到,在計算機中,我們使用取模運算符%可以直接得到餘數,然後對該整數除以2,再取餘數,直到商為0為止。
  • 二進位、八進位、十進位、十六進位相互轉化
    十進位 數值是0~9 逢十進一    2.二進位 數值是0~1 逢二進一    3.八進位 數值是0~7 逢八進一    4.十六進位 數值0~9 A~F 逢十六進一二、數位    一個數字所在的位置    1000   4位 個0 十1 百2千3    10101 二進位  5位  01234
  • 二進位,八進位,十進位,十六進位轉換詳解~
    ①、數碼:用來表示進位數的元素。                                二進位:0,1。                                八進位:0,1,2,3,4,5,6,7                                十進位:0,1,2,3,4,5,6,7,8,9。
  • PPC和MIPS指令集下二進位代碼中函數參數個數的識別方法
    radare2是最新的二進位分析工具,它擁有強大的分析功能,支持對不同架構語言的反彙編,在「aaa」命令中實現了對二進位函數分析的功能,在對PPC和MIPS指令集的二進位函數進行分析時,發現函數參數個數的識別效果比較差。為提高函數參數個數的識別準確率,本文提出並實現了一種基於函數調用關係的函數參數個數識別算法——Findargs,用於識別PPC和MIPS指令集下二進位可執行代碼中函數的參數個數。
  • 閒聊數制形式:二進位、八進位、十進位、十六進位
    我們這裡提到的十進位就是告訴你「逢十進一」,低位的數值滿十以後向前面的高位進一,然後低位數值變為零,那麼相應的二進位、八進位、十六進位就可以理解為「逢二進一」、「逢八進一」、「逢十六進一」。羅馬數字進位可以簡單地看成一個個周期的循環往復,隨著周期的不斷出現,數值在不停的增加或者減少,上面提到的進位屬於不同的數制形式,生活中的數制形式遠不止這麼幾種,如我們每天都要用到的時鐘,時鐘的秒針是滿六十進一,二十四小時制是說滿二十四個小時後向前進
  • 計算機等級考試詳解:十進位數92轉換為二進位數!
    計算機等級考試詳解:十進位數92轉換為二進位數!本經驗由宗龍龍原創,全文共1000多字,閱讀需要14分鐘,如果文中存在錯誤,還請大家多多指點,我會積極改進的!14、十進位數92轉換為二進位數是()。A)01011100B)01101100C)10101011D)01011000(圖片來源於網絡)這一題主要考察的是十進位與二進位的相互轉換問題。
  • 二進位數的運算規則
    二進位數之間可以執行算術運算和邏輯運算,其規則簡單,容易實現。產生借位)     1 1 0 1   1 - 0 = 1          -)0 1 1 1   1 - 1 = 0
  • 二進位、八進位、十進位與十六進位
    在計算機語言中常用的進位有二進位、八進位、十進位和十六進位,十進位是最主要的表達形式。二進位是0和1; 八進位是0-7;十進位是0-9;十六進位是0-9,A-F(大小寫均可)。也可以這樣簡單記憶,假設是n進位的話,基數就是【0,n-1】的數字,基數的個數和進位值相同,二進位有兩個基數,十進位有十個基數,依次類推。
  • 二進位、八進位、十進位、十六進位轉換計算方法
    進位也就是進位位,我們常用的進位包括:二進位、八進位、十進位與十六進位,它們之間區別在於數運算時是逢幾進一位。比如二進位是逢2進一位,十進位也就是我們常用的0-9是逢10進一位。
  • 兩個二進位數相加
    陸小鳳原創本文講解「兩個二進位數相加」的算法題。
  • 使用Windows 10內置的計算器,可快速將十進位數轉換為二進位數
    接下來我們需要了解什麼是二進位和二進位數?20世紀被稱作第三次科技革命 的重要標誌之一是計算機的發明與應用,因為數字計算機只能識別和處理由0或1符號串組成的代碼,二進位正是計算技術中廣泛採用的一種數制,由德國數理哲學大師萊布尼茨於1679年發明。二進位數是用0和1兩個數碼來表示的數。它的基數為2,進位規則是「逢二進一」,借位規則是「借一當二」。