https://leetcode.com/problems/reverse-bits/
Reverse bits of a given 32 bits unsigned integer.
Note:
Follow up:
If this function is called many times, how would you optimize it?
Example 1:
Input: n = 00000010100101000001111010011100
Output: 964176192 (00111001011110000010100101000000)
Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
Example 2:
Input: n = 11111111111111111111111111111101
Output: 3221225471 (10111111111111111111111111111111)
Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111.
Constraints:
方法一:双指针 + 位操作(我写的)
PS:
在二进制中,设置特定的数位:
方法二:位操作(乾坤大挪移)
for 8 bit binary number abcdefgh, the process is as follow:
abcdefgh -> efghabcd -> ghefcdab -> hgfedcba
方法三:类似队列 + 位操作
We first intitialize result to 0. We then iterate from 0 to 31 (an integer has 32 bits). In each iteration:
We first shift result to the left by 1 bit. Then, if the last digit of input n is 1, we add 1 to result. To find the last digit of n, we just do: (n & 1).
Example, if n=5 (101), n&1 = 101 & 001 = 001 = 1;however, if n = 2 (10), n&1 = 10 & 01 = 00 = 0).
Finally, we update n by shifting it to the right by 1 (n >>= 1). This is because the last digit is already taken care of, so we need to drop it by shifting n to the right by 1.
At the end of the iteration, we return result.
Example, if input n = 13 (represented in binary as 0000,0000,0000,0000,0000,0000,0000,1101, the “,” is for readability),
calling reverseBits(13) should return:
1011,0000,0000,0000,0000,0000,0000,0000
Here is how our algorithm would work for input n = 13:
Initially, result = 0 = 0000,0000,0000,0000,0000,0000,0000,0000,
n = 13 = 0000,0000,0000,0000,0000,0000,0000,1101
Starting for loop:
i = 0:
result = result << 1 = 0000,0000,0000,0000,0000,0000,0000,0000.
n&1 = 0000,0000,0000,0000,0000,0000,0000,1101
& 0000,0000,0000,0000,0000,0000,0000,0001
= 0000,0000,0000,0000,0000,0000,0000,0001 = 1
therefore result = result + 1 =
0000,0000,0000,0000,0000,0000,0000,0000 + 0000,0000,0000,0000,0000,0000,0000,0001
= 0000,0000,0000,0000,0000,0000,0000,0001 = 1
Next, we right shift n by 1 (n >>= 1) (i.e. we drop the least significant bit) to get:
n = 0000,0000,0000,0000,0000,0000,0000,0110.
We then go to the next iteration.
i = 1:
result = result << 1 = 0000,0000,0000,0000,0000,0000,0000,0010;
n&1 = 0000,0000,0000,0000,0000,0000,0000,0110 &
0000,0000,0000,0000,0000,0000,0000,0001
= 0000,0000,0000,0000,0000,0000,0000,0000 = 0;
therefore we don’t increment result.
We right shift n by 1 (n >>= 1) to get:
n = 0000,0000,0000,0000,0000,0000,0000,0011.
We then go to the next iteration.
i = 2:
result = result << 1 = 0000,0000,0000,0000,0000,0000,0000,0100.
n&1 = 0000,0000,0000,0000,0000,0000,0000,0011 &
0000,0000,0000,0000,0000,0000,0000,0001 =
0000,0000,0000,0000,0000,0000,0000,0001 = 1
therefore result = result + 1 =
0000,0000,0000,0000,0000,0000,0000,0100 +
0000,0000,0000,0000,0000,0000,0000,0001 =
result = 0000,0000,0000,0000,0000,0000,0000,0101
We right shift n by 1 to get:
n = 0000,0000,0000,0000,0000,0000,0000,0001.
We then go to the next iteration.
i = 3:
result = result << 1 = 0000,0000,0000,0000,0000,0000,0000,1010.
n&1 = 0000,0000,0000,0000,0000,0000,0000,0001 &
0000,0000,0000,0000,0000,0000,0000,0001 =
0000,0000,0000,0000,0000,0000,0000,0001 = 1
therefore result = result + 1 =
= 0000,0000,0000,0000,0000,0000,0000,1011
We right shift n by 1 to get:
n = 0000,0000,0000,0000,0000,0000,0000,0000 = 0.
Now, from here to the end of the iteration, n is 0, so (n&1)
will always be 0 and and n >>=1 will not change n. The only change
will be for result <<=1, i.e. shifting result to the left by 1 digit.
Since there we have i=4 to i = 31 iterations left, this will result
in padding 28 0’s to the right of result. i.e at the end, we get
result = 1011,0000,0000,0000,0000,0000,0000,0000
This is exactly what we expected to get.
方法四:比方法三精简些
public class ReverseBits {
// 方法一:双指针 + 位操作
public int reverseBits1(int n) {
int p1 = Integer.MIN_VALUE, p2 = 1;
do {
boolean b1 = (n & p1) == 0;
boolean b2 = (n & p2) == 0;
if (b1 ^ b2) {
n = b1 ? (n | p1) : (n & ~p1);
n = b2 ? (n | p2) : (n & ~p2);
}
p1 >>>= 1;
p2 <<= 1;
} while (p1 > p2);
return n;
}
// 方法二:乾坤大挪移
public int reverseBits2(int 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);
n = ((n & 0xaaaaaaaa) >>> 1) | ((n & 0x55555555) << 1);
return n;
}
// 方法三:队列 + 位操作
public int reverseBits3(int n) {
if (n == 0)
return 0;
int result = 0;
for (int i = 0; i < 32; i++) {
result <<= 1;
if ((n & 1) == 1)
result++;// 可写成 result += n&1;
n >>= 1;
}
return result;
}
// 方法四:比方法三精简些
public int reverseBits4(int n) {
int result = 0;
for (int i = 0; i < 32; i++)
result = (result << 1) + (n >> i & 1);
return result;
}
}
import static org.junit.Assert.*;
import org.junit.Test;
public class ReverseBitsTest {
@Test
public void test() {
ReverseBits obj = new ReverseBits();
assertEquals(Integer.parseInt("00000000000000001111111111111110", 2), //
obj.reverseBits1(Integer.parseInt("01111111111111110000000000000000", 2)));
assertEquals(964176192, obj.reverseBits1(Integer.parseInt("00000010100101000001111010011100", 2)));
assertEquals(-1073741825, obj.reverseBits1(-3));
assertEquals(Integer.parseInt("00000000000000001111111111111110", 2), //
obj.reverseBits2(Integer.parseInt("01111111111111110000000000000000", 2)));
assertEquals(964176192, obj.reverseBits2(Integer.parseInt("00000010100101000001111010011100", 2)));
assertEquals(-1073741825, obj.reverseBits2(-3));
assertEquals(Integer.parseInt("00000000000000001111111111111110", 2), //
obj.reverseBits3(Integer.parseInt("01111111111111110000000000000000", 2)));
assertEquals(964176192, obj.reverseBits3(Integer.parseInt("00000010100101000001111010011100", 2)));
assertEquals(-1073741825, obj.reverseBits3(-3));
assertEquals(Integer.parseInt("00000000000000001111111111111110", 2), //
obj.reverseBits4(Integer.parseInt("01111111111111110000000000000000", 2)));
assertEquals(964176192, obj.reverseBits4(Integer.parseInt("00000010100101000001111010011100", 2)));
assertEquals(-1073741825, obj.reverseBits4(-3));
}
}