日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

剑指Offer #11 二进制中1的个数(想不到的骚操作)

發(fā)布時(shí)間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 剑指Offer #11 二进制中1的个数(想不到的骚操作) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目來(lái)源:牛客網(wǎng)-劍指Offer專題
題目地址:二進(jìn)制中1的個(gè)數(shù)

題目描述

輸入一個(gè)整數(shù),輸出該數(shù)二進(jìn)制表示中1的個(gè)數(shù)。其中負(fù)數(shù)用補(bǔ)碼表示。

題目解析

對(duì)于這種涉及位運(yùn)算的題目,我們首先要了解基本的位運(yùn)算,我們可以看這篇文章:C++描述的位運(yùn)算總結(jié)

(PS:本文的圖例用的是8位的整數(shù),int有32位,畫出來(lái)也不美觀呀)

下面先給說(shuō)一種因?yàn)榇嬖谪?fù)數(shù)而錯(cuò)誤的做法:

  • 先通過(guò) ‘&1’ 操作來(lái)判斷 nnn 的最低位否為1,若為1,則計(jì)數(shù)器 cntcntcnt 的值加1;
  • 然后利用 ‘>>1’ 操作將 nnn 右移一位;
  • 最后重復(fù)上述兩步操作,直到 nnn 的值為0,得出 cntcntcnt 的值即為該數(shù)二進(jìn)制表示中1的個(gè)數(shù)。

這種方法在 nnn 為正數(shù)的時(shí)候是沒(méi)有問(wèn)題的,因?yàn)檎龜?shù)進(jìn)行右移操作的時(shí),最低位舍棄,最高位補(bǔ)0。過(guò)程如圖所示:

但是負(fù)數(shù)進(jìn)行右移操作的時(shí),最低位舍棄,最高位的是1(過(guò)程如下圖),這樣經(jīng)過(guò)多次以后,所有數(shù)位都會(huì)變成1,進(jìn)而產(chǎn)生死循環(huán)。

下面給大家一共四種不同的正確解法:

方法一:
利用Integer內(nèi)置的toBinaryString()方法將 nnn 轉(zhuǎn)換為二進(jìn)制字符串,然后二進(jìn)制串中的0全部消掉,最后求得的字符串長(zhǎng)度就是該數(shù)二進(jìn)制表示中1的個(gè)數(shù)。

public class Solution {public int NumberOf1(int n) {return Integer.toBinaryString(n).replaceAll("0", "").length();} }

方法二:
這是對(duì)上面講到的錯(cuò)誤方法的改進(jìn),由于左移操作是最高位舍棄,最低位補(bǔ)0,我們選擇讓 nnn 不變, 對(duì) ‘&1’ 中的1進(jìn)行左移,直到移動(dòng)31位為止

由上圖的兩種情況可以看出,當(dāng)1移動(dòng)了 iii 位之后,若 nnn 的第 iii 位為1,進(jìn)行&運(yùn)算的結(jié)果為 (1<<i)(1 << i)(1<<i),否則為0。于是,我們就可以利用他們?yōu)榕袛鄺l件來(lái)計(jì)算1的個(gè)數(shù)啦~

public class Solution {public int NumberOf1(int n) {int cnt = 0;for(int i = 0; i < 32; i++) {//if ((n & (1 << i)) == (1 << i))也是可行的if ((n & (1 << i)) != 0)cnt++;}return cnt;} }

方法三:
這種方法是很久之前zls師兄告訴我的,沒(méi)想到今天才派上用場(chǎng)(我記憶力真好 )。

理論:nnnn?1n-1n?1 進(jìn)行 &\&& 運(yùn)算可以把 nnn 的二進(jìn)制表示的右邊第一個(gè)1變成0

根據(jù)上面給的理論,我們只要知道 nnn 可以進(jìn)行多少次這樣的操作,就可以得到 nnn 的二進(jìn)制表示中1的個(gè)數(shù),下圖以n=29為例展示這個(gè)過(guò)程:

如果對(duì)上訴過(guò)程感受不深,可以手動(dòng)計(jì)算多幾組數(shù)據(jù),雖然這種方法感覺(jué)起來(lái)比較笨,但卻是理解的好辦法。能用上這種方法,面試應(yīng)該沒(méi)問(wèn)題了。

public class Solution {public int NumberOf1(int n) {int cnt = 0;while (n != 0) {n = n & (n - 1);cnt++;}return cnt;} }

方法四:
這是在牛客網(wǎng)評(píng)論區(qū)看到做法,由Holiday_12138發(fā)表,但是ta并沒(méi)有給出具體思路,我也參悟不出來(lái),我打算以后理解了再更新這部分,也歡迎各位大佬提供解釋。(做法真的太騷了 )

public class Solution {public int NumberOf1(int n) {int temp = n;temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >>> 1);temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >>> 2);temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >>> 4);temp = (temp & 0x00ff00ff) + ((temp & 0xff00ff00) >>> 8);temp = (temp & 0x0000ffff) + ((temp & 0xffff0000) >>> 16);return temp;} }

如果本文對(duì)你有所幫助,要記得點(diǎn)贊哦~

總結(jié)

以上是生活随笔為你收集整理的剑指Offer #11 二进制中1的个数(想不到的骚操作)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。