国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

【建議收藏】面試官會的位運算奇淫技巧

開發 后端
本篇的內容為位運算的介紹和一些比較經典的位運算問題進行介紹分析,當然,位運算這么牛,后面肯定還是要歸納總結的。

[[377917]]

 前言

位運算隱藏在編程語言的角落中,其神秘而又強大,暗藏內力,有些人光聽位運算的大名的心中忐忑,還有些人更是一看到位運算就遠遠離去,我之前也是。但狡猾的面試官往往喜歡搞偷襲,抓住我們的弱點搞我們,為了防患于未然,特記此篇!

本篇的內容為位運算的介紹和一些比較經典的位運算問題進行介紹分析,當然,位運算這么牛,后面肯定還是要歸納總結的。

認識位運算

什么是位運算?

  • 程序中的所有數在計算機內存中都是以二進制的形式儲存的。位運算就是直接對整數在內存中的二進制位進行操作。

位運算就是直接操作二進制數,那么有哪些種類的位運算呢?

常見的運算符有與(&)、或(|)、異或(^)、取反(~)、左移(<<)、右移(>>是帶符號右移 >>>無符號右移動)。下面來細看看每一種位運算的規則。

位運算 & (與)

規則:二進制對應位兩兩進行邏輯AND運算(只有對應位的值都是 1 時結果才為 1, 否則即為 0)即 0&0=0,0&1=0,1&1=1

例如:2 & -2


位運算 | (或)

規則:二進制對應位兩兩進行邏輯或運算(對應位中有一 個為1則為1) 即0|0=0,0|1=1,1|1=1

例如:2 | -2


位運算 ^ (異或)

規則:二進制對應位兩兩進行邏輯XOR (異或) 的運算(當對應位的值不同時為 1, 否則為 0)即0^0=1, 0^1=0, 1^1=1

例如:2 ^ -2

 


 

按位取反~

規則:二進制的0變成1,1變成0。

移位運算符

左移運算<<:左移后右邊位補 0

右移運算>>:右移后左邊位補原最左位值(可能是0,可能是1)

右移運算>>>:右移后左邊位補 0

  • 對于左移運算符<<沒有懸念右側填個零無論正負數相當于整個數乘以2。
  • 而右移運算符就有分歧了,分別是左側補0>>>和左側補原始位>>,如果是正數沒爭議左側都是補0,達到除以2的效果;如果是負數的話左側補0>>>那么數值的正負會發生改變,會從一個負數變成一個相對較大的正數。而如果是左側補原始位(負數補1)>>那么整個數還是負數,也就是相當于除以2的效果。

下面這張圖可以很好的幫助你理解負數的移位運算符:


到這里,我想你應該對位運算有了初步的認識,在這里把上面提到的部分案例執行對比一下讓你看一下可能會理解的更清晰:


位運算小技巧

在這里有些常用的位運算小技巧。

判斷奇偶數

正常判斷奇數偶數的時候我們會這樣寫:

  1. if( n % 2 == 1) 
  2.     // n 是個奇數 

使用位運算可以這么寫:

  1. if(n & 1 == 1){ 
  2.     // n 是個奇數。 

其核心就是判斷二進制的最后一位是否為1,如果為1那么結果加上2^0=1一定是個奇數,否則就是個偶數。

交換兩個數

對于傳統的交換兩個數,我們需要使用一個變量來輔助完成操作,可能會是這樣:

  1. int team = a; 
  2. a = b; 
  3. b = team; 

但是使用位運算可以不需要借助額外空間完成數值交換:

  1. a=a^b;//a=a^b 
  2. b=a^b;//b=(a^b)^b=a^0=a 
  3. a=a^b;//a=(a^b)^(a^b^b)=0^b=0 

原理已經寫在注釋里面了,是不是感覺非常diao呢?

二進制枚舉

在遇到子集問題的處理時候,我們有時候會借助二進制枚舉來遍歷各種狀態(效率大于dfs回溯)。這種就屬于排列組合的問題了,對于每個物品(位置)來說,就是使用和不使用的兩個狀態,而在二進制中剛好可以用1和0來表示。而在實現上,通過枚舉數字范圍分析每個二進制數字各符號位上的特征進行計算求解操作即可。


二進制枚舉的代碼實現為:

  1. for(int i = 0; i < (1<<n); i++) //從0~2^n-1個狀態 
  2.   for(int j = 0; j < n; j++) //遍歷二進制的每一位 共n位 
  3.   { 
  4.     if(i & (1 << j))//判斷二進制數字i的第j位是否存在 
  5.     { 
  6.       //操作或者輸出 
  7.     } 
  8.   } 

 位運算經典問題

有了上面的位運算基礎,我們怎么用位運算處理實際問題呢?或者有哪些經典的問題可以用位運算來解決呢。

不用加減乘除做加法

題目描述

  • 寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。

分析:這道題咋一聽可能沒啥思路,簡單研究一下位運算還是能獨立推出來和理解的。

當然,解決這題前,需要了解上面的四種位運算。還要知道二進制的運算:0+0=0,0+1=1,1+1=0(進位)

對于加法的一個二進制運算。如果不進位那么就是非常容易的。這時候相同位都為0則為0,0和1則為1.滿足這種運算的異或(不相同取1,相同取0)和或(有一個1則為1)都能滿足.

但事實肯定有進位的運算啊!看到上面操作的不足之后,我們肯定還需要解決進位的問題對于進位的兩數相加,這種核心思想為:

  • 用兩個數,一個正常m相加(不考慮進位的)。用異或a^b就是滿足這種要求,先不考慮進位(如果沒進位那么就是最終結果)。另一個專門考慮進位的n。兩個1需要進位。所以我們用a&b與記錄需要進位的。但是還有個問題,進位的要往上面進位,所以就變成這個需要進位的數左移一位。
  • 然后就變成m+n重新迭代開始上面直到不需要進位的(即n=0時候)。

實現代碼為:

  1. public class Solution { 
  2.      public int Add(int num1,int num2) { 
  3.   /* 
  4.    *  5+3   5^3(0110)   5&3(0001)  
  5.    *  0101     
  6.    *  0011  
  7.    */ 
  8.   int a=num1^num2; 
  9.   int b=num1&num2; 
  10.   b=b<<1; 
  11.   if(b==0)return a; 
  12.   else { 
  13.    return Add(a, b); 
  14.   }         
  15.   } 

當然,這里也可以科普一下二進制求加法:average = (a&b) + ((a^b)>>1) ;

二進制中1的個數

這是一道經典題,在劍指offer上也有對應題目,其具體題目要求輸入一個整數,輸出該數二進制表示中1的個數(其中負數用補碼表示)。

對于這個問題,不用位運算將它轉成二進制字符串直接枚舉字符'1'的個數也可以直接求出來,但是這樣做是沒有靈魂的并且效率比較差。這里提供兩種解決思路

法一:大家知道每個類型的數據它的背后實際都是二進制操作。大家知道int的數據類型的范圍是(-2^31,2^31 -1)。并且int有32位。但是并非32位全部用來表示數據。真正用來表示數據大小的也是31位。最高位用來表示正負。

首先要知道:


其次還要知道位運算&與。兩個十進制與運算.每一位同1為1。所以我們用2的正數次冪與知道的數分別進行與運算操作。如果結果不為0,那么就說明這位為1.(前面31個都是大于0的最后一個與結果是負數但是如果該位為1那么結果肯定不為0)


具體代碼實現為:

  1. public int NumberOf1(int n) { 
  2.   int va=0; 
  3.   for(int i=0;i<32;i++) 
  4.   { 
  5.     if((n&(1<<i))!=0) 
  6.     {            
  7.       va++; 
  8.     } 
  9.   } 
  10.   return va;        

 法二是運用n&(n-1)。n如果不為0,那么n-1就是二進制第一個為1的變為0,后面全為1.這樣的n&(n-1)一次運算就相當于把最后一個1變成0.這樣一直到運算的數為0停止計算次數就好了,如下圖共進行三次運算那么n的二進制中就有三個1。

實現代碼為:

  1. public class Solution { 
  2.     public int NumberOf1(int n) { 
  3.     int count=0; 
  4.     while (n!=0) { 
  5.      n=n&(n-1); 
  6.      count++; 
  7.     } 
  8.     return count
  9.  } 

只出現一次的(一個)數字①

問題描述:

  • 給定一個非空整數數組,除了某個元素只出現一次以外,其余每個元素均出現兩次。找出那個只出現了一次的元素。
  • 說明:你的算法應該具有線性時間復雜度。你可以不使用額外空間來實現嗎?

分析:

這是一道簡單的面試題,面試官常問怎么樣用不太復雜的方法找出數組中僅出現一次的數字(其他均出現兩次),暴力枚舉或者使用其他的存儲結構都不夠優化,而這個問題最高效的答案就是使用位運算。首先你要注意兩點:

  • 0和任意數字進行異或操作結果為數字本身.
  • 兩個相同的數字進行異或的結果為0.

具體的操作就是用0開始和數組中每個數進行異或,得到的值和下個數進行異或,最終獲得的值就是出現一次(奇數次)的值。


  1. class Solution { 
  2.     public int singleNumber(int[] nums) { 
  3.         int value=0; 
  4.         for(int i=0;i<nums.length;i++) 
  5.         { 
  6.             value^=nums[i]; 
  7.         } 
  8.         return value; 
  9.     } 

 只出現一次的(一個)數字②

問題描述:

  • 給定一個非空整數數組,除了某個元素只出現一次以外,其余每個元素均出現了三次。找出那個只出現了一次的元素。
  • 說明:你的算法應該具有線性時間復雜度。你可以不使用額外空間來實現嗎?

分析:

這題和上一題的思路略有不同,這題其他數字出現了3次,那么我們如果直接使用位運算異或操作的話無法直接找到結果,就需要巧妙的運用二進制的其他特性:判斷整除求余操作。即判斷所有數字二進制1的總個數和0的總個數一定有一個不是三的整數倍,如果0不是三的整數倍那么就說明結果的該位二進制數字為0,同理否則為1.


在具體的操作實現上,問題中給出數組中的數據在int范圍之內,那么我們就可以在實現上可以對int的32個位每個位進行依次判斷該位1的個數求余3后是否為1,如果為1說明結果該位二進制為1可以將結果加上去。最終得到的值即為答案。

具體代碼為:

  1. class Solution { 
  2.     public int singleNumber(int[] nums) { 
  3.         int value=0; 
  4.         for(int i=0;i<32;i++) 
  5.         { 
  6.             int sum=0; 
  7.             for(int num:nums) 
  8.             { 
  9.                 if(((num>>i)&1)==1) 
  10.                 { 
  11.                     sum++; 
  12.                 } 
  13.             } 
  14.             if(sum%3==1) 
  15.                 value+=(1<<i); 
  16.         } 
  17.         return value; 
  18.     } 

 只出現一次的(兩個)數字③

題目描述

  • 一個整型數組里除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。

思路:

上面的問題處理和理解起來可能比較容易,但是這個問題可能稍微復雜一點,但是這題可以通過特殊的手段轉化為上面只出現一次的一個數字問題來解決,當然核心的位運算也是異或^。

具體思路就是想辦法將數組邏輯上一分為二!先異或一遍到最后得到一個數,得到的肯定是a^b(假設兩個數值分別為a和b)的值。在看異或^的屬性:不同為1,相同為0. 也就是說最終這個結果的二進制為1的位置上a和b是不相同的。而我們可以找到這個第一個不同的位,然后將數組中的數分成兩份,該位為0的進行異或求解得到其中一個結果a,該位為1的進行異或求解得到另一個結果b。

具體可以參考下圖流程:


實現代碼為:

  1. public int[] singleNumbers(int[] nums) { 
  2.     int value[]=new int[2]; 
  3.     if(nums.length==2) 
  4.         return  nums; 
  5.     int val=0;//異或求的值 
  6.     for(int i=0;i<nums.length;i++) 
  7.     { 
  8.         val^=nums[i]; 
  9.     } 
  10.     int index=getFirst1(val); 
  11.     int num1=0,num2=0; 
  12.     for(int i=0;i<nums.length;i++) 
  13.     { 
  14.         if(((nums[i]>>index)&1)==0)//如果這個數第index為0 和num1異或 
  15.             num1^=nums[i]; 
  16.         else//否則和 num2 異或 
  17.             num2^=nums[i]; 
  18.     } 
  19.     value[0]=num1; 
  20.     value[1]=num2; 
  21.     return  value; 
  22.  
  23. private int getFirst1(int val) { 
  24.     int index=0; 
  25.     while (((val&1)==0&&index<32)) 
  26.     { 
  27.         val>>=1;// val=val/2 
  28.         index++; 
  29.     } 
  30.     return index

結語

當然,上面的問題可能有更好的解法,也有更多經典位運算問題將在后面歸納總結,希望本篇的位運算介紹能夠讓你有所收獲,對位運算能有更深一點的認識。對于很多問題例如博弈問題等二進制位運算能夠很巧妙的解決問題,日后也會分享相關內容,敬請期待!

 

責任編輯:姜華 來源: bigsai
相關推薦

2020-12-14 08:17:50

代碼

2024-05-10 09:22:08

?瀏覽器開發

2024-08-08 16:53:17

2015-08-13 10:29:12

面試面試官

2020-03-06 15:36:01

Redis內存宕機

2022-05-23 08:43:02

BigIntJavaScript內置對象

2010-08-12 16:28:35

面試官

2017-11-09 18:10:59

程序員騰訊面試官

2023-02-16 08:10:40

死鎖線程

2021-05-17 08:37:46

GETPOSTHTTP

2018-10-22 14:28:26

面試官數據公司

2025-07-25 01:45:00

RAG模型技術

2021-11-08 09:18:01

CAS面試場景

2024-06-13 08:01:19

2024-11-19 15:13:02

2021-12-25 22:31:10

MarkWord面試synchronize

2023-12-27 18:16:39

MVCC隔離級別幻讀

2025-03-10 00:00:00

property?attributeHTML

2025-03-10 11:40:00

前端開發HTML

2025-04-08 00:00:00

@AsyncSpring異步
點贊
收藏

51CTO技術棧公眾號

91丨porny丨户外露出| 国产伦精品一区二区三区四区免费 | av成人app永久免费| 成人免费xxxxx在线观看| 国产一区二区三区四| 色久视频在线观看| 国产一区二区动漫| 久久精品免费一区二区三区| 日韩a∨精品日韩在线观看| 色综合亚洲欧洲| 久久久久久久久成人| 日韩电影大全在线观看| 一区二区三区中文免费| videos性欧美另类高清| 99精品99久久久久久宅男| 久久久亚洲午夜电影| 欧美14一18处毛片| 91精品在线影院| 中文字幕av在线一区二区三区| freexxx性亚洲精品| 亚洲精品日韩激情在线电影| 久久综合狠狠综合久久激情| 性欧美猛交videos| 91久久久久久| 自拍偷拍国产亚洲| 高清av一区二区三区| 日本婷婷久久久久久久久一区二区| 亚洲色图视频免费播放| 久久亚洲人体| 伊人婷婷久久| 91麻豆精品国产91久久久久久久久 | 成人三级网址| 国产综合在线观看视频| 国产精品久久夜| 97人人模人人爽人人喊38tv| 久久精品人人做人人爽人人| 国产一区二区主播在线| 国产精品综合久久久久久| 亚洲激情自拍偷拍| 国产成人影院| 又黄又爽在线观看| 99在线首页视频| 亚洲黄页网在线观看| 久久91精品国产91久久小草| 欧美国产视频| 99免费视频观看| 91视频免费在线观看| 一区二区三区毛片| 国产三线在线| 国产精品自拍偷拍视频| 国产高清视频一区| 国产精品拍天天在线| 亚州国产精品| 欧美a级片网站| 欧美日韩在线不卡一区| 图片区小说区国产精品视频| 国产伦精品一区二区三区在线播放 | 免费网站免费进入在线| 亚洲综合社区网| 黄色精品在线看| 成人久久综合| 亚洲美女主播视频免费观看| 97精品国产aⅴ7777| 日本一区二区久久| 国产精品18hdxxxⅹ在线| 午夜视频你懂的| 91爱爱小视频k| 亚洲日穴在线视频| 九九热精品视频在线观看| 可播放的18gay1069| 国产精品美女在线| 日韩欧美在线第一页| 亚洲成人精品| 黄色片免费在线观看| 亚洲精品免费在线看| 亚洲天堂免费视频| 国产婷婷色一区二区三区四区| 国产精品丝袜在线播放| 午夜男人视频在线观看| 666精品在线| 日韩一级成人av| 国产精品一级黄| 亚洲精品影片| 最全影音av资源中文字幕在线| 国产经典一区二区三区| 日韩欧美成人一区二区| 国产精品538一区二区在线| 亚洲精品影片| 青青草免费观看免费视频在线| 久久久久久久久久久久久久一区 | 国产一区二区导航在线播放| 123成人网| 99久久久精品视频| 日韩欧美手机在线| 国产激情综合五月久久| 在线视频日本亚洲性| 欧美日本在线观看| 一区二区在线看| 中文字幕一区二| 国产午夜亚洲精品午夜鲁丝片 | 中文精品视频一区二区在线观看| 日本人成精品视频在线| 夜夜躁日日躁狠狠久久88av | 97超碰人人看人人| 黑人欧美xxxx| 在线免费精品视频| 国产精品日韩一区二区| 久久久久久日产精品| 蜜桃精品wwwmitaows| 欧美激情视频在线播放| 男人天堂新网址| 国产精品黄色av| 日韩精品一区二区在线| 91视频一区二区| 亚洲最大黄网| 欧美123区| 手机福利视频欧美| 亚洲精品日韩精品| 午夜精品久久17c| 制服丝袜在线91| 国产亚洲精品超碰| 欧美激情综合| 激情综合五月天| 国产麻豆视频一区| 成人短视频下载| 亚洲美女在线一区| 色婷婷久久一区二区三区麻豆| 欧美日韩国产影片| 亚洲免费精彩视频| 麻豆国产精品va在线观看不卡| 欧美日韩国产成人高清视频| 成年无码av片在线| 国内精品在线一区| 国产精品日韩一区二区| 在线观看视频黄色| 亚洲视频在线a| 久久久久久久久久久久久久国产| 国产欧美精品日韩| 精品国产91久久久久久久妲己| 日韩精品中文字幕在线一区| 992tv成人免费影院| 99热在线看| 一本色道久久综合| 麻豆网在线观看| 成人综合网址| 欧美一级黄色录像片| 91精品国自产在线观看| 欧美成人精品一区二区| 日韩精品一区二区三区在线播放| 综合电影一区二区三区| 久久av资源站| 亚洲天堂偷拍| 亚洲人和日本人hd| 成人精品三级| a在线免费观看| 污污网站在线| 8x8x8x视频在线观看| 很污的网站在线观看| 久久精品二区| 91免费欧美精品| 91干在线观看| 日韩中文字幕免费看| 亚洲成人激情在线| 欧美另类变人与禽xxxxx| 午夜精品一区二区三区免费视频 | 精品国产伦一区二区三区观看方式 | 亚洲精品国产福利| 色综合夜色一区| 亚洲精品亚洲人成人网在线播放| 不卡的av网站| 精品在线免费观看| 亚洲美女啪啪| 一精品久久久| sdde在线播放一区二区| 懂色av一区二区| 精品国产亚洲一区二区三区| 视频在线日韩| 三妻四妾的电影电视剧在线观看| 欧美另类极品| 成人免费一区二区三区视频网站| 免费观看黄色网| 三级黄色网址| 日本aa大片在线播放免费看| www.com黄色片| 99热com| 99国产精品久久| 亚洲影院色无极综合| 日本在线观看免费视频| 久久资源综合| 疯狂做受xxxx欧美肥白少妇| 狠狠色综合日日| 久久国产精品72免费观看| 男女视频一区二区| 日韩中文字幕91| 国产欧美日韩一级| 国产精品一卡| 老牛国产精品一区的观看方式| 宅男噜噜噜66一区二区| 午夜亚洲视频| 久久66热re国产|