题目链接: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.youkuaiyun.com/maojudong/article/details/6235274