1、位运算
我们最简单的思路就是使用位运算,每次选择原二进制数中的一位,将其移动到新的二进制数的对应位置。我们每次选择原二进制数的最后一位,将其右移至对应位置后放到新的二进制数中,而后我们右移原二进制数对下一位进行操作。如此重复直至超过32位或原二进制数为0。
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t res = 0;
for (int i = 0; i < 32 && n > 0; ++i) {
res |= (n & 1) << (31 - i);
n >>= 1;
}
return res;
}
};
2、分治法
为了实现逆序,最快的方法是使用分治法。我们可以考虑一个简单的例子,假如我们要将12345678进行逆序操作,使用分治法的流程如下:
1、将奇偶位上的数字进行交换,之后为21436587;2、将每两位数字之间进行交换,之后为43218765;3、将每四位数字之间进行交换,之后为87654321。最终我们通过3次操作实现了逆序。
同理,我们对32位数字进行逆序操作时,我们只需要在此基础上增加一步每八位数字进行交换即可,最终我们将每十六位数字交换位置即可获得最终的逆序结果。最终流程如下:
class Solution {
private:
const uint32_t M1 = 0x55555555; // 01010101010101010101010101010101
const uint32_t M2 = 0x33333333; // 00110011001100110011001100110011
const uint32_t M4 = 0x0f0f0f0f; // 00001111000011110000111100001111
const uint32_t M8 = 0x00ff00ff; // 00000000111111110000000011111111
public:
uint32_t reverseBits(uint32_t n) {
n = n >> 1 & M1 | (n & M1) << 1;
n = n >> 2 & M2 | (n & M2) << 2;
n = n >> 4 & M4 | (n & M4) << 4;
n = n >> 8 & M8 | (n & M8) << 8;
return n >> 16 | n << 16;
}
};