位運算基礎css
說到與(&)、或(|)、非(~)、異或(^)、位移等位運算,就得說到位運算的各類奇淫巧技,下面分運算符說明。git
1. 與(&)github
計算式 a&b,a、b各位中同爲 1 才爲 1,不然爲0,a&1和a%2效果同樣;來看兩道典型的題目,第1道計算整數二進制中 1 的位數:數組
//191. Number of 1 Bits int hammingWeight(uint32_t n) { int res=0; while(n!=0){ n=n&(n-1); ++res; } return res; }
n=n&(n-1)表明去掉整數n二進制中最左側爲 1 的位,例如n=12,則:less
n -> 1 1 0 0 & n-1 -> 1 0 1 1 ------------------ 1 0 0 0
第2道判斷一個數是否爲4的乘方數(不能用loop解):oop
//342. Power of Four bool isPowerOfFour(int num) { if(num==INT_MIN) return false; return !(num&(num-1)) && (num&0x55555555); }
以上0x55555555的二進制表示爲……01010101 (偶數位爲0、奇數位爲1),像這樣tricky的數還有:ui
0xaaaaaaaa : 10101010101010101010101010101010 (偶數位爲1,奇數位爲0) 0x33333333 : 00110011001100110011001100110011 (1和0每隔兩位交替出現) 0xcccccccc : 11001100110011001100110011001100 (0和1每隔兩位交替出現) 0x0f0f0f0f : 00001111000011110000111100001111 (1和0每隔四位交替出現) 0xf0f0f0f0 : 11110000111100001111000011110000 (0和1每隔四位交替出現)
相關LeetCode題:spa
201. Bitwise AND of Numbers Range 題解code
2. 或(|)
計算式a|b,a、b各位中有一個爲1則結果爲1;來看一道題:有正整數n,求小於或等於n的2的最大乘方數(不能用loop解):
int largest_power(ing N) { N = N | (N>>1); N = N | (N>>2); N = N | (N>>4); N = N | (N>>8); N = N | (N>>16); return (N+1)>>1; }
看起來是否是至關tricky,其思路是用或運算將右邊位數置爲1,例如n=01010,經過或操做n變爲01111,則n+1爲10000,所求爲01000;更詳細解釋見 這裏
相關LeetCode題:
3. 異或(^)
計算式a^b,a、b對應位相同爲0,相異則爲1;根據異或性質有a^a=0,a^0=a,利用該性質可解決136. Single Number:
//136. Single Number int singleNumber(vector<int>& nums) { int res=0; for(auto x:nums) res^=x; return res; }
相關LeetCode題:
4. 位移
a<<1效果至關於a*2(不超出數值類型範圍狀況下),a>>1效果至關於a/2,位移經常使用於按位輪詢。
相關LeetCode題:
有意思的時當咱們的目光放到bit的維度,一些問題能夠按位來求解,例如169. Majority Element求數組中出現次數大於一半的數:
//169. Majority Element int majorityElement(vector<int>& nums) { int mask=1,size=nums.size(),ret=0; for(int i=0;i<32;i++){ int count=0; for(int j=0;j<size;j++){ if(nums[j]&mask) count++; if(count>size/2){ ret|=mask; //逐位計算結果break; } } mask<<=1; } return ret; }
相關LeetCode題:
421. Maximum XOR of Two Numbers in an Array 題解
使用bit表示數據
在一些場景下咱們但願用bit來表示數據,或節省空間或利用bit的運算特性來表示狀態轉換。
相關LeetCode題: