初識Leetcode----學習(二十)【顛倒二進位制位、位1的個數】
阿新 • • 發佈:2018-11-09
①顛倒二進位制位
顛倒給定的 32 位無符號整數的二進位制位。
示例:
輸入: 43261596 輸出: 964176192 解釋: 43261596 的二進位制表示形式為 00000010100101000001111010011100 , 返回 964176192,其二進位制表示形式為 00111001011110000010100101000000 。
進階:
如果多次呼叫這個函式,你將如何優化你的演算法?
1.本蒻的簡單直接的寫法,將二進位制位儲存到容器中,然後翻轉進行求和:
class Solution { public: uint32_t reverseBits(uint32_t n) { vector<int> vec; //儲存二進位制位 int cnt = 0; while (n > 0) { vec.push_back(n % 2); n /= 2; cnt++; } while (cnt < 32) { vec.push_back(0); cnt++; } reverse(vec.begin(), vec.end()); //翻轉 uint32_t sum = 0; for (int i = 0; i < 32; ++i) { if (vec[i] == 1) { sum += pow(2, i); //求和 } } return sum; } };
2.從右向左遍歷二進位制位,如果當前二進位制位為1,則結果res左移並加1,否則左移,將當前二進位制位右移,依次遍歷得到結果:
具體分析:
輸入數n:20 則二進位制位表示:10100
進行遍歷:n從低位開始遍歷,即從0到1
第一位:0 res:0
第二位:0 res:0
第三位:1 res:此時左移加1,為1
第四位:0 res:1
第五位:1 res:左移加1得到結果為5
class Solution { public: uint32_t reverseBits(uint32_t n) { uint32_t res = 0; for (int i = 0;i < 32; ++i) { if (n & 1 == 1) //n的最低位為1,則結果res左移並加1 res = (res<<1) + 1; else //否則結果res左移 res = res << 1; n = n >> 1; //取n的下一位 } return res; } };
3.直接將n右移i位,通過‘&’1取出該位,加到左移1位後的res即得結果(實質與上述思路一致):
class Solution { public: uint32_t reverseBits(uint32_t n) { uint32_t res = 0; for (int i = 0; i < 32; ++i) { res = (res << 1) + (n >> i & 1); //將n右移i位,然後與1取出該位加到結果中 } return res; } };
4.將n右移i位,通過與1取出該位,然後將其左移(31-i)位,然後與結果res進行或運算,即可得到結果:
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t res = 0;
for (int i = 0; i < 32; ++i) {
res |= ((n >> i) & 1) << (31 - i); //n右移i位與1取出該位,左移31-i位得到翻轉位,然後與結果res或運算
}
return res;
}
};
②位1的個數
編寫一個函式,輸入是一個無符號整數,返回其二進位制表示式中數字位數為 ‘1’ 的個數(也被稱為漢明重量)。
示例 :
輸入: 11
輸出: 3
解釋: 整數 11 的二進位制表示為 00000000000000000000000000001011
示例 2:
輸入: 128 輸出: 1 解釋: 整數 128 的二進位制表示為 00000000000000000000000010000000
1.此題與上題類似,會做一道就會另一道,也是n右移i位與1取出該位和1判斷,如果相等則計數加1:
class Solution {
public:
int hammingWeight(uint32_t n) {
int cnt = 0;
for (int i = 0; i < 32; ++i)
{
if ((n >> i) & 1 == 1) //n右移i位與1取出該位,和1判斷
++cnt;
}
return cnt;
}
};