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

2020-12-23 酷扯兒

本文轉載自【微信公眾號:五角錢的程式設計師,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));

}

}

相關焦點

  • 18.1在 O(1) 時間內刪除鍊表節點(劍指 Offer 題解Java版)
    O(1)時間刪除該結點。解題思路①如果該節點不是尾節點,那麼可以直接將下一個節點的值賦給該節點,然後令該節點指向下下個節點,再刪除下一個節點,時間複雜度為O(1)。②否則,就需要先遍歷鍊表,找到節點的前一個節點,然後讓前一個節點指向null,時間複雜度為O(N)。
  • 二維數組中的查找(劍指 Offer 題解Java版)
    tpId=13&tqId=11154&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github題目描述給定一個二維數組,其每一行從左到右遞增排序
  • 二進位、十進位和十六進位
    1) 十進位就不多說了,逢十進位,一個位有十個值: 0 ~ 9,我們的生活中到處都是它的身影。二進位就是逢二進位,它的一個位只有兩個值:0 和 1,但它卻是實現計算機系統的最基本的理論基礎,計算機(包括單片機)晶片是基於成萬上億個的開關管組合而成的,他們每一個都只能有開和關兩種狀態,再難找出第三個狀態了(不要辯解半開半關這個狀態,它是不穩定態,是極力避免的),所以他們只能對應於二進位的 1 和 0 兩個值,而沒有 2、3、4.,理解二進位對於理解計算機的本質很有幫助。
  • 二進位數字易經
    乾一 八卦由三個陰、陽符號(在《二進位數字易經》中為0、1符號)組成,這三個符號稱為三爻(音yáo),從左到右,依次稱為:初爻、中爻、上爻。而六十四卦,由內卦和外卦接合組成「六爻卦」,即每一卦由六個陰、陽符號(在《二進位數字易經》中為0、1符號)組成,如《坤為地》卦可表示為:000  000;《山地剝》卦可表示為:000  001 。這六個爻,從左到右,依次稱為:初爻、二爻、三爻、四爻、五爻和上爻。
  • 剪繩子(劍指 Offer 題解Java版)
    如果出現了,就從已經切好長度為 3 的繩子中拿出一段與長度為 1 的繩子重新組合,把它們切成兩段長度為 2 的繩子。證明:當 n >= 5 時,3(n - 3) - n = 2n - 9 > 0,且 2(n - 2) - n = n - 4 > 0。因此在 n >= 5 的情況下,將繩子剪成一段為 2 或者 3,得到的乘積會更大。
  • 使用Swing製作進位轉化器
    進位轉化1.各進位之間的轉化在計算機科學中,常用的進位有二進位、八進位、十進位和十六進位。在開發過程中使用比較多的是二進位和十進位的。如果涉及一些字節編碼操作,十六進位也會用得到,甚至可能會用到三十二進位。1.1 十進位向其它進位轉化以正常的十進位數為標準,如果將一個十進位數轉化成二進位數。可以使用除法取餘的方式進行,在下圖中我們用二進位和八進位進行舉例:
  • 重建二叉樹(劍指 Offer 題解Java版)
    tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github題目描述根據二叉樹的前序遍歷和中序遍歷的結果
  • 真有小夥伴不知道浮點數如何轉二進位嗎?
    浮點數在計算機中是如何表示的?學過 《計算機組成原理》 或者類似 《計算機系統》 這些課程的小夥伴們應該都知道,浮點數在計算機中的存儲方式遵循IEEE 754 浮點數計數標準,可以表示為:浮點數的精度是由尾數的位數來決定的:對於float型浮點數,尾數部分23位,換算成十進位就是 2^23=8388608,所以十進位精度只有6 ~ 7位;對於double型浮點數,尾數部分52位,換算成十進位就是 2^52 = 4503599627370496,所以十進位精度只有15 ~ 16位所以,浮點數交給計算機存儲的時候,可能會有
  • 用兩個棧實現隊列(劍指 Offer 題解Java版)
    那麼怎麼插入一個新元素呢,比如插入d,那麼可以讓d直接入棧到stack1。繼續刪除隊列隊首元素,從stack2中刪除c,然後把d彈出stack1併入棧stack2,然後從stack2中直接pop。通過觀察我們發現,如果進行虛擬隊列的push操作,可以把元素直接入棧到stack1;如果進行虛擬隊列的pop操作,如果stack2為空,那麼把stack1中所有的元素彈出併入棧到stack2,然後對stack2進行pop操作;如果stack2不為空,那麼直接對stack2進行pop操作,到這裡你是不是已經思路變得清晰了。
  • 從十六進位到存檔修改——吞食魚1存檔修改教程
    因此,只要使用十六進位編輯器來打開它,就可以看到這個文件的一些本質了  為了能夠更好地理解本文,在這裡將會先簡單地介紹十六進位及其應用的相關知識。如果只是想修改存檔,則可以直接跳過「相關技術準備」這節,這並不會影響閱讀十六進位的表示  我們在日常生活中使用的都是十進位數,它們由十個數字組成:0、1、2、3、4、5、6、7、8、9。
  • 數值的整數次方(劍指 Offer 題解Java版)
    解題思路下面的討論中 x 代表 base,n 代表 exponent。IDEA*/public class Solution {public double power(double base,int exponent){if (exponent == 0)return 1;
  • keil c51如何實現2進位操作
    #define LongToBin(n) \(本文引用地址:http://www.eepw.com.cn/article/201611/315987.htm (n>>21)&0x80 \ (n>>18)&0x40 \ (n>>15
  • 二進位究竟是由誰發明的?是萊布尼茨,還是來源於中國的周易
    並推算出了著名的二進位。對以後的數學發展產生了深遠的影響。然而,這種二進位和中國《周易》裡的內容相吻合,以至於讓二進位的發明權有了爭議。到底是誰發明了二進位?是萊布尼茨還是古老的中國人?那些認為二進位是萊布尼茨發明的人,他們的依據是。萊布尼茨會在收到在中國的法國傳教士白晉寄給他的伏羲六十四卦次序圖和方位圖之前根本沒有見過太極圖。
  • 二叉樹的下一個結點(劍指 Offer 題解Java版)
    tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github題目描述給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回 。
  • 四方語(4Case)特殊字符及其二進位編碼
    「四方字庫」共有1格字16個(字根),2格字240個,3格字3840個,4格字61440個。我們用「1-3格字」來表示常用漢字,4格字表示生僻字和特殊符號。英文字母二進位編碼的基本原則為:1、確保4個字根組合而成的字形儘量與字母相似。這樣設計的好處是,根據字母的形狀,能拆出二進位數字,從而得知字母的「四方字庫編號」。2、確保大寫字母的編號大於小寫字母,並且每個小寫字母都是從大寫字母變動1-2個字根而來。
  • 數理轉換,互為質數與進位轉換
    先說一下進位:十進位裡逢十進一,1/2就是0.5;2進位裡逢二進一,1/2就是0.1;4進位裡逢4進一,1/2就是0.2;6進位裡逢6進一,1/2就是0.3。那在3進位裡呢?注意:十進位小數是常用的小數進位,但小數進位不一定是十進位。如17/32採用32進位,則小數表示為0.17。有限小數的本質是分母因式分解後的幾組因數,必須都是進位數的因數,比如1/2,1/4,1/5,1/8,1/10,1/16,1/20,它們之所以是10進位的有限小數,就是因為它們的分母最終只能分解為2和5這兩組進位因數。20進位的進位因數仍是2和5。
  • C語言常用的進位轉換工具函數盤點!爺爺再也不用擔心我不會進位...
    03 字符串轉十進位 (1)若帶負號,代碼實現: 04 十進位轉字符串 如果只是單個十進位轉字符串,使用sprintf函數就可以了。 如果是十進位數組:
  • 日版《戰爭機器》?賽博朋克風射擊大作《二進位領域》安利
    鋪了這麼多,本期還是想給大家扯一部產出自日本的賽博朋克風格遊戲佳作,《二進位領域》(Binary Domain)。這部可以被稱為是日版《戰爭機器》的線性流程第三人稱射擊遊戲由出品過《如龍》系列的名越埝洋擔任製作人,還支持玩家用語言下達指令。雖然已經有點年頭,但放現在也不算落伍,流程也更是一絕。
  • 20.表示數值的字符串(劍指 Offer 題解,面試遇到好多次)
    :xianglin965】經微信公眾號授權轉載,如需轉載與原文作者聯繫文章目錄題目描述思路思路一:思路二:例如,字符串"+100",「5e2」,"-123",「3.1416"和」-1E-16"都表示數值。但是"12e",「1a3.14」,「1.2.3」,"±5"和"12e+4.3"都不是。
  • 《狩獵》二進位年代
    在這個標籤紛飛,帽子亂扣的年代,政治正確打個勾、政治不正確打個叉。到了如今,人類的思考能力居然變得如此的二進位。人們面對著由紛繁複雜的自己搞出來的爛攤子,心如亂麻,徹底放棄了,不再探索、不再商榷、不再理論,卻用最懶惰簡易的方法,方便地貼標籤站隊識人。