题目描述
思路分析
一个数的二进制逆置,其实就是从低位往高位依次遍历每一个二进制位,然后将该二进制位左移一定的值,比如如果是最低位, 则左移31位(二进制位是从0开始,因此最大左移31位,而不是32),如果是最后一位,则左移0位,然后将每一位左移后的值相加即可。
代码实现1
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
// 7--->111
// 111000000000...
uint32_t res = 0;
int i = 31;
while(i >= 0) {
// 得到当前位的值 0 或者 1
int cur_bit_value = n % 2;
// 左移一定的位,并加到原数值里
res += (cur_bit_value << i);
// 原数右移一位,将次低位变为最低位,继续循环
n >>= 1;
i--;
}
return res;
}
};
复制代码
代码实现2(某网友的分治思路)
分而治之的思想,先将高16位与低16位交换,再同时交换每16位中的高低两个8位,然后基本类似地二分做下去,直到最后是每两位之间交换高低两个一位。可见,解法二要比解法一更高效,解法一是 O( sizeof(int) ),解法二是 O( log_2 sizeof(int) )。
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
n = (n >> 16) | (n << 16);
n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);//注意优先级
n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2); // 4位的低2位为3,高2位为12(即c)
n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1); // 相当于&1010 &0101
return n;
}
};
复制代码