题目描述
题目分析
题目本身很简单,没觉得有什么技巧可以再进行优化了,觉得位运算是无法打乱相对顺序的,而这里需要进行镜像颠倒的操作。因此就踏实地写了一个循环。
在使用位运算得到每一位的时候,我吸取了经验,用一个临时变量保存,这样每次只用进行一次移位操作,这样是一个小小的优化。
class Solution {
public:uint32_t reverseBits(uint32_t n) {uint32_t ans = 0;uint32_t t1 = 1 << 31;uint32_t t2 = 1 << 0;for (uint32_t i = 0; i < 32; ++i) {if (n & t1) {ans += t2;}t1 >>= 1;t2 <<= 1;}return ans;}
};
然后做完去看题解,发现题解用到说是叫位运算分治。其实就是简单的分治,只不过这里是一个很小的数字,可以用位运算进行分治操作。因为大小位32,所以分治的次数是5,我们可以顺序执行这5次分治,用位运算进行。
如果不是数字,并且位数更多的话,使用分治是没有意义的,复杂度也是O(n),甚至常数更大。
官方题解
这样好骚啊。。。
class Solution {
private:const uint32_t M1 = 0x55555555; // 01010101010101010101010101010101const uint32_t M2 = 0x33333333; // 00110011001100110011001100110011const uint32_t M4 = 0x0f0f0f0f; // 00001111000011110000111100001111const uint32_t M8 = 0x00ff00ff; // 00000000111111110000000011111111public: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;}
};