[LeetCode][190][Reverse Bits]

来源:互联网 发布:中文数据库 编辑:程序博客网 时间:2024/05/01 19:01

题目链接:https://leetcode.com/problems/reverse-bits/

题目描述:

Reverse bits of a given 32 bits unsigned integer.

For example, given input 43261596 (represented in binary as00000010100101000001111010011100), return 964176192 (represented in binary as00111001011110000010100101000000).

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

Related problem: Reverse Integer

题目的大概意思就是把一个数按位反转。

看到这个题目,可以用数组将每一位存上,然后再做二进制转换成十进制的运输。不过一想就知道这样很麻烦,所以再加思考,就知道要用位运算啦~

这个题的思路是将操作数n向右移位,再把得到的数依次向左移位,最后得到所要结果。

那么这里的问题就是怎样依次得到n向右移位的结果,和怎样将得到的结果依次向左移位放在一个数中。

首先是依次获得n向右移位最右边的数,只要与1做“与运算”即可,即,n & 1,用一个中间变量temp保存;然后n >> 1;

向左移动的时候再用1做与运算就很麻烦了,因为左移的时候一个数的末尾自动填0补足,所以要用0做“或运算”,即 0 | temp,用一个数保存结果,因为这个数也是最终结果,这里我就命名为result;然后result << 1;

这里还有移位多少次的问题,是用sizeof,sizeof得到的是字节数,所以移动次数等于 8 * sizeof(n)。整理下代码如下:

<span style="font-size:12px;">uint32_t reverseBits(uint32_t n) {    int i;    unsigned result = 0;    unsigned temp = 0;    for(i = 0; i < 8*sizeof(n); i++){        result <<= 1;        temp = n & 1;        n >>= 1;        result |= temp;    }        return result;}</span>

当然我不是一下子就得到了这段代码了,因为我也不是很熟悉位运算,首先第一次犯的错误是只给数字移位,却不清楚移位是不改变原操作数的,代码是这样的:

<span style="font-size:12px;">uint32_t reverseBits(uint32_t n) {    int i;    int result = 0;    int temp = 0;    for(i = 0; i < 8*sizeof(n); i++){        temp = n & 1;        n >> 1;         // 应该是 n >>= 1;        result |= temp;        result << 1;    // 应该是 result <<= 1;    }        return result;}</span>
但是这样的结果仍然不对,在IDE里跑了一遍,把每次的temp,n,result都输出一遍,才发现了是最后一次循环的result多移位了一次,所以应该把result的移位运算放到for循环的一开始,另外,对于i移动的次数,最好是在for循环的外面赋给一个变量,否则每次进入for循环都要算一遍,这不是个好习惯,最后应该更改为:

<span style="font-size:12px;">uint32_t reverseBits(uint32_t n) {    int i;    unsigned result = 0;    unsigned temp = 0;    int count = 8*sizeof(n);    //这里将移动次数赋值给一个变量,使得for循环在判断条件的时候减少运算,是个好习惯哟~    for(i = 0; i < count; i++){        result <<= 1;           //正确方法应该将result的移位放到开始,而且因为这里result初始值是0,所以不会有影响。        temp = (n >> i) & 1;    //n每次要移动的位数就等于i,所以可以改成这样        result |= temp;    }        return result;}</span>

总结:

1. 移位运算是不改变原操作数的值的;

2.灵活运用移位运算,根据需求选择合适的运算和操作数,即0、1、&、|、~、^的结合,会使代码的逻辑更严谨。


这个题还有个Follow up:
If this function is called many times, how would you optimize it?

上网搜了下其他人的解法,有一个讲的很详细,参见:http://blog.csdn.net/maojudong/article/details/6235274



0 0