LeetCode(190) Reverse Bits

题目如下:

Reverse bits of a given 32 bits unsigned integer.


For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).


Follow up:
If this function is called many times, how would you optimize it?


分析如下:

类似revers integer的思路, 注意比特运算。

比如value = (value<<1 )|((n&mask)>>i);  这句后的n&mask会逐渐取得n的第0,1,2,, , , 31位的数,取得之后,还需要把它加到逐渐滚动的value上去。

我采用的是模拟reverse integer的方法,把每次取得的n&mask的数表达为第0位的数之后再添加到value上去。


我的代码:

//9ms
class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t value = 0;
        uint32_t mask = 1;
        for (uint32_t i = 0; i < 32; ++i) {
            value = (value<<1 )|((n&mask)>>i);
            mask <<=1;
        }
        return value;
    }
};


另外一种写法是,

基本和上面一致。区别在于,第一种做法是每次移动mask。第二种做法是每次右移输入的数字本身,mask永远是1.

//9ms
class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t value = 0;
        for (uint32_t i = 0; i < 32; ++i) {
            value = (value<<1 )|((n>>i) & 1);
        }
        return value;
    }
};


follow up

这里找到了follow up的思考方向,还是很巧妙的。

Remember how merge sort works? Let us use an example of n == 8 (one byte) to see how this works:

       01101001
    /                  \
  0110          1001
  /      \            /     \
 01     10     10     01
 /\       /\       /\         /\
0 1   1  0   1  0      0 1
The first step is to swap all odd and even bits. After that swap consecutive pairs of bits, and so on…
Therefore, only a total of log(n) operations are necessary.
The below code shows a specific case where n == 32, but it could be easily adapted to larger n‘s as well.


//9ms
class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t x = n;
        x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
        x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2);
        x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4);
        x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8);
        x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);
        return x;
    }
};

上面的16进制数字中:

0x55555555 =         0101 0101 0101 0101 0101 0101 0101 0101

0xAAAAAAAA =     1010 1010 1010 1010 1010 1010 1010 1010

0x33333333 =        0011 0011 0011 0011 0011 0011 0011 0011

0xCCCCCCCC =   1100 1100 1100 1100 1100 1100 1100 1100


参考资料:

http://articles.leetcode.com/2011/08/reverse-bits.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值